2
0
Эх сурвалжийг харах

Merge branch 'development' into hlcode_absolute_jump_offsets

Simon Krajewski 1 жил өмнө
parent
commit
73cde7b83c
100 өөрчлөгдсөн 2629 нэмэгдсэн , 1860 устгасан
  1. 137 105
      .github/workflows/main.yml
  2. 4 0
      .vscode/schemas/define.schema.json
  3. 4 1
      Earthfile
  4. 9 4
      Makefile
  5. 5 2
      Makefile.win
  6. 2 1
      dune
  7. 1 1
      extra/BUILDING.md
  8. 180 5
      extra/CHANGES.txt
  9. 1 1
      extra/EnvVarUpdate.nsh
  10. 37 38
      extra/ImportAll.hx
  11. 3 3
      extra/choco/haxe.nuspec
  12. 4 5
      extra/github-actions/build-mac.yml
  13. 8 1
      extra/github-actions/build-windows.yml
  14. 0 6
      extra/github-actions/cache-opam.yml
  15. 4 2
      extra/github-actions/install-nsis.yml
  16. 2 7
      extra/github-actions/install-ocaml-libs-windows.yml
  17. 30 8
      extra/github-actions/install-ocaml-windows.yml
  18. 11 7
      extra/github-actions/install-ocaml-windows64.yml
  19. 4 0
      extra/github-actions/test-windows.yml
  20. 56 53
      extra/github-actions/workflows/main.yml
  21. 1 1
      extra/haxelib_src
  22. 1 1
      extra/installer.nsi
  23. 2 2
      extra/mac-installer/scripts/neko-postinstall.sh
  24. 15 11
      extra/release-checklist.txt
  25. 7 5
      haxe.opam
  26. 3 3
      libs/extc/extc.ml
  27. 21 21
      libs/extc/extc_stubs.c
  28. 2 2
      libs/extc/process_stubs.c
  29. 7 1
      libs/extlib-leftovers/dune
  30. 5 5
      libs/extlib-leftovers/multiArray.ml
  31. 1 1
      libs/extlib-leftovers/uTF8.ml
  32. 7 1
      libs/ilib/dune
  33. 2 2
      libs/ilib/peReader.ml
  34. 7 1
      libs/javalib/dune
  35. 7 1
      libs/neko/dune
  36. 2 2
      libs/neko/ncompile.ml
  37. 27 4
      libs/objsize/c_objsize.c
  38. 9 6
      libs/pcre2/pcre2_stubs.c
  39. 7 1
      libs/swflib/dune
  40. 1 1
      libs/swflib/swfParser.ml
  41. 1 1
      libs/swflib/swfPic.ml
  42. 7 1
      libs/ttflib/dune
  43. 1 1
      libs/ttflib/tTFParser.ml
  44. 7 1
      libs/ziplib/dune
  45. 8 8
      libs/ziplib/zip.ml
  46. 7 1
      plugins/example/dune
  47. 199 37
      src-json/define.json
  48. 2 1
      src-json/meta.json
  49. 10 0
      src-json/warning.json
  50. 7 1
      src-prebuild/dune
  51. 68 28
      src-prebuild/prebuild.ml
  52. 24 24
      src/codegen/codegen.ml
  53. 14 13
      src/codegen/dotnet.ml
  54. 14 7
      src/codegen/gencommon/castDetect.ml
  55. 13 21
      src/codegen/gencommon/closuresToClass.ml
  56. 5 5
      src/codegen/gencommon/dynamicFieldAccess.ml
  57. 0 1
      src/codegen/gencommon/dynamicOperators.ml
  58. 2 3
      src/codegen/gencommon/enumToClass.ml
  59. 0 1
      src/codegen/gencommon/enumToClass2.ml
  60. 18 6
      src/codegen/gencommon/expressionUnwrap.ml
  61. 1 1
      src/codegen/gencommon/filterClosures.ml
  62. 1 2
      src/codegen/gencommon/fixOverrides.ml
  63. 14 12
      src/codegen/gencommon/gencommon.ml
  64. 0 1
      src/codegen/gencommon/initFunction.ml
  65. 9 11
      src/codegen/gencommon/overloadingConstructor.ml
  66. 18 16
      src/codegen/gencommon/realTypeParams.ml
  67. 32 26
      src/codegen/gencommon/reflectionCFs.ml
  68. 4 10
      src/codegen/gencommon/renameTypeParameters.ml
  69. 15 10
      src/codegen/gencommon/switchToIf.ml
  70. 6 2
      src/codegen/gencommon/unnecessaryCastsRemoval.ml
  71. 16 9
      src/codegen/gencommon/unreachableCodeEliminationSynf.ml
  72. 37 35
      src/codegen/java.ml
  73. 69 33
      src/codegen/javaModern.ml
  74. 4 13
      src/codegen/overloads.ml
  75. 21 17
      src/codegen/swfLoader.ml
  76. 26 13
      src/compiler/args.ml
  77. 28 10
      src/compiler/compilationContext.ml
  78. 153 96
      src/compiler/compiler.ml
  79. 18 12
      src/compiler/displayOutput.ml
  80. 20 18
      src/compiler/displayProcessing.ml
  81. 11 9
      src/compiler/generate.ml
  82. 14 3
      src/compiler/helper.ml
  83. 401 0
      src/compiler/messageReporting.ml
  84. 18 20
      src/compiler/retyper.ml
  85. 91 413
      src/compiler/server.ml
  86. 7 3
      src/compiler/serverCompilationContext.ml
  87. 2 1
      src/compiler/serverConfig.ml
  88. 7 1
      src/compiler/serverMessage.ml
  89. 23 21
      src/context/abstractCast.ml
  90. 168 129
      src/context/common.ml
  91. 42 55
      src/context/display/deprecationCheck.ml
  92. 29 30
      src/context/display/diagnostics.ml
  93. 82 34
      src/context/display/diagnosticsPrinter.ml
  94. 5 231
      src/context/display/display.ml
  95. 18 15
      src/context/display/displayEmitter.ml
  96. 8 8
      src/context/display/displayException.ml
  97. 30 25
      src/context/display/displayFields.ml
  98. 125 13
      src/context/display/displayJson.ml
  99. 7 10
      src/context/display/displayTexpr.ml
  100. 6 9
      src/context/display/displayToplevel.ml

+ 137 - 105
.github/workflows/main.yml

@@ -10,13 +10,9 @@ jobs:
     env:
     env:
       ACTIONS_ALLOW_UNSECURE_COMMANDS: true
       ACTIONS_ALLOW_UNSECURE_COMMANDS: true
       PLATFORM: windows64
       PLATFORM: windows64
-      OPAMYES: 1
-      OPAMROOT: D:\.opam
-      CYG_MIRROR: http://mirrors.kernel.org/sourceware/cygwin/
       ARCH: 64
       ARCH: 64
       MINGW_ARCH: x86_64
       MINGW_ARCH: x86_64
-      CYGWIN_SETUP: https://cygwin.com/setup-x86_64.exe
-      CYG_ROOT: C:/cygwin64
+      CYG_ROOT: D:\cygwin
     steps:
     steps:
       - uses: actions/checkout@main
       - uses: actions/checkout@main
         with:
         with:
@@ -27,12 +23,20 @@ jobs:
           echo "C:\msys64\usr\bin" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append
           echo "C:\msys64\usr\bin" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append
           rm C:\msys64\usr\bin\bash.exe
           rm C:\msys64\usr\bin\bash.exe
 
 
-      - name: Cache opam
-        id: cache-opam
-        uses: actions/[email protected]
+      - name: choco install nsis
+        uses: nick-invision/retry@v2
         with:
         with:
-          path: D:\.opam
-          key: ${{ runner.os }}64-${{ hashFiles('./opam', './libs/') }}
+          timeout_minutes: 10
+          max_attempts: 10
+          command: choco install --no-progress nsis.portable --version 3.09 -y
+
+      - name: choco install things
+        shell: pwsh
+        run: choco install --no-progress curl wget 7zip.portable -y
+
+      - name: Prepend Chocolatey path
+        shell: pwsh
+        run: Write-Host "::add-path::C:\ProgramData\chocolatey\bin"
 
 
       - name: Install Neko from S3
       - name: Install Neko from S3
         shell: pwsh
         shell: pwsh
@@ -46,47 +50,33 @@ jobs:
       - name: Print Neko version
       - name: Print Neko version
         run: neko -version 2>&1
         run: neko -version 2>&1
 
 
-      - name: choco install nsis
-        uses: nick-invision/retry@v1
+      - name: Setup ocaml
+        uses: ocaml/setup-ocaml@v2
         with:
         with:
-          timeout_minutes: 10
-          max_attempts: 10
-          command: choco install --no-progress nsis.portable --version 3.02 -y
-      - name: choco install things
-        shell: pwsh
-        run: choco install --no-progress curl wget 7zip.portable -y
-      - name: Prepend Chocolatey path
-        shell: pwsh
-        run: Write-Host "::add-path::C:\ProgramData\chocolatey\bin"
+          ocaml-compiler: 4.08.1
+          opam-repositories: |
+            opam-repository-mingw: https://github.com/ocaml-opam/opam-repository-mingw.git#sunset
+            default: https://github.com/ocaml/opam-repository.git
+          opam-local-packages: |
+            haxe.opam
 
 
-      - name: Install OCaml
+      - name: Install dependencies
         shell: pwsh
         shell: pwsh
         run: |
         run: |
           Set-PSDebug -Trace 1
           Set-PSDebug -Trace 1
-          curl.exe -fsSL -o cygwin-setup.exe --retry 3 $($env:CYGWIN_SETUP)
-          Start-Process -FilePath "cygwin-setup.exe" -ArgumentList "-B -q -R $($env:CYG_ROOT) -l C:/tmp -s $($env:CYG_MIRROR) -P default -P make -P git -P zlib-devel -P rsync -P patch -P diffutils -P curl -P unzip -P tar -P m4 -P perl -P libpcre2-devel -P mbedtls-devel -P mingw64-$($env:MINGW_ARCH)-zlib -P mingw64-$($env:MINGW_ARCH)-gcc-core -P mingw64-$($env:MINGW_ARCH)-pcre2" -Wait -RedirectStandardOutput cygwin-setup-out.txt
-          Get-Content cygwin-setup-out.txt
-          curl.exe -fsSL -o "opam.tar.xz" --retry 3 https://github.com/fdopen/opam-repository-mingw/releases/download/0.0.0.2/opam$($env:ARCH).tar.xz
           curl.exe -fsSL -o "libmbedtls.tar.xz" --retry 3 https://github.com/Simn/mingw64-mbedtls/releases/download/2.16.3/mingw64-$($env:MINGW_ARCH)-mbedtls-2.16.3-1.tar.xz
           curl.exe -fsSL -o "libmbedtls.tar.xz" --retry 3 https://github.com/Simn/mingw64-mbedtls/releases/download/2.16.3/mingw64-$($env:MINGW_ARCH)-mbedtls-2.16.3-1.tar.xz
           & "$($env:CYG_ROOT)/bin/bash.exe" @('-lc', 'curl -L https://cpanmin.us | perl - App::cpanminus')
           & "$($env:CYG_ROOT)/bin/bash.exe" @('-lc', 'curl -L https://cpanmin.us | perl - App::cpanminus')
           & "$($env:CYG_ROOT)/bin/bash.exe" @('-lc', 'cpanm IPC::System::Simple module')
           & "$($env:CYG_ROOT)/bin/bash.exe" @('-lc', 'cpanm IPC::System::Simple module')
           & "$($env:CYG_ROOT)/bin/bash.exe" @('-lc', 'cpanm String::ShellQuote')
           & "$($env:CYG_ROOT)/bin/bash.exe" @('-lc', 'cpanm String::ShellQuote')
           & "$($env:CYG_ROOT)/bin/bash.exe" @('-lc', 'echo "$OLDPWD"')
           & "$($env:CYG_ROOT)/bin/bash.exe" @('-lc', 'echo "$OLDPWD"')
           & "$($env:CYG_ROOT)/bin/bash.exe" @('-lc', 'cd "$OLDPWD" && tar -C / -xvf libmbedtls.tar.xz')
           & "$($env:CYG_ROOT)/bin/bash.exe" @('-lc', 'cd "$OLDPWD" && tar -C / -xvf libmbedtls.tar.xz')
-          & "$($env:CYG_ROOT)/bin/bash.exe" @('-lc', 'cd "$OLDPWD" && tar -xf opam.tar.xz')
-          & "$($env:CYG_ROOT)/bin/bash.exe" @('-lc', 'cd "$OLDPWD" && bash opam${ARCH}/install.sh')
 
 
       - name: Install OCaml libraries
       - name: Install OCaml libraries
-        if: steps.cache-opam.outputs.cache-hit != 'true'
         shell: pwsh
         shell: pwsh
         run: |
         run: |
           Set-PSDebug -Trace 1
           Set-PSDebug -Trace 1
-          & "$($env:CYG_ROOT)/bin/bash.exe" @('-lc', 'opam init mingw "https://github.com/fdopen/opam-repository-mingw.git#opam2" --comp 4.07.0+mingw${ARCH}c --switch 4.07.0+mingw${ARCH}c --auto-setup --yes 2>&1')
-          & "$($env:CYG_ROOT)/bin/bash.exe" @('-lc', 'opam update --yes 2>&1')
-          & "$($env:CYG_ROOT)/bin/bash.exe" @('-lc', 'cd "$OLDPWD" && opam pin add haxe . --kind=path --no-action --yes 2>&1')
-          & "$($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')
+          opam install haxe --deps-only
+          opam list
 
 
       - name: Expose mingw dll files
       - name: Expose mingw dll files
         shell: pwsh
         shell: pwsh
@@ -116,8 +106,15 @@ jobs:
           & "$($env:CYG_ROOT)/bin/bash.exe" @('-lc', 'cd "$OLDPWD" && cygcheck ./haxelib.exe')
           & "$($env:CYG_ROOT)/bin/bash.exe" @('-lc', 'cd "$OLDPWD" && cygcheck ./haxelib.exe')
           & "$($env:CYG_ROOT)/bin/bash.exe" @('-lc', 'cd "$OLDPWD" && ls ./out')
           & "$($env:CYG_ROOT)/bin/bash.exe" @('-lc', 'cd "$OLDPWD" && ls ./out')
 
 
+      - name: Check artifact
+        shell: bash
+        run: |
+          ls out
+          # Output should contain binaries zip, installer zip and nupkg
+          [ $(ls -1 out | wc -l) -eq "3" ]
+
       - name: Upload artifact
       - name: Upload artifact
-        uses: actions/[email protected]
+        uses: actions/upload-artifact@v3
         with:
         with:
           name: win${{env.ARCH}}Binaries
           name: win${{env.ARCH}}Binaries
           path: out
           path: out
@@ -128,13 +125,9 @@ jobs:
     env:
     env:
       ACTIONS_ALLOW_UNSECURE_COMMANDS: true
       ACTIONS_ALLOW_UNSECURE_COMMANDS: true
       PLATFORM: windows
       PLATFORM: windows
-      OPAMYES: 1
-      OPAMROOT: D:\.opam
-      CYG_MIRROR: http://mirrors.kernel.org/sourceware/cygwin-archive/20221123
       ARCH: 32
       ARCH: 32
       MINGW_ARCH: i686
       MINGW_ARCH: i686
-      CYGWIN_SETUP: https://cygwin.com/setup-x86.exe
-      CYG_ROOT: C:/cygwin
+      CYG_ROOT: D:\cygwin
     steps:
     steps:
       - uses: actions/checkout@main
       - uses: actions/checkout@main
         with:
         with:
@@ -145,12 +138,20 @@ jobs:
           echo "C:\msys64\usr\bin" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append
           echo "C:\msys64\usr\bin" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append
           rm C:\msys64\usr\bin\bash.exe
           rm C:\msys64\usr\bin\bash.exe
 
 
-      - name: Cache opam
-        id: cache-opam
-        uses: actions/[email protected]
+      - name: choco install nsis
+        uses: nick-invision/retry@v2
         with:
         with:
-          path: D:\.opam
-          key: ${{ runner.os }}32-${{ hashFiles('./opam', './libs/') }}
+          timeout_minutes: 10
+          max_attempts: 10
+          command: choco install --no-progress nsis.portable --version 3.09 -y
+
+      - name: choco install things
+        shell: pwsh
+        run: choco install --no-progress curl wget 7zip.portable -y
+
+      - name: Prepend Chocolatey path
+        shell: pwsh
+        run: Write-Host "::add-path::C:\ProgramData\chocolatey\bin"
 
 
       - name: Install Neko from S3
       - name: Install Neko from S3
         shell: pwsh
         shell: pwsh
@@ -164,48 +165,52 @@ jobs:
       - name: Print Neko version
       - name: Print Neko version
         run: neko -version 2>&1
         run: neko -version 2>&1
 
 
-      - name: choco install nsis
-        uses: nick-invision/retry@v1
+      - name: Setup ocaml
+        id: ocaml
+        continue-on-error: true
+        uses: kLabz/setup-ocaml@win32
         with:
         with:
-          timeout_minutes: 10
-          max_attempts: 10
-          command: choco install --no-progress nsis.portable --version 3.02 -y
-      - name: choco install things
-        shell: pwsh
-        run: choco install --no-progress curl wget 7zip.portable -y
-      - name: Prepend Chocolatey path
-        shell: pwsh
-        run: Write-Host "::add-path::C:\ProgramData\chocolatey\bin"
+          ocaml-compiler: 4.08.1
+          opam-depext: false
+          opam-repositories: |
+            opam-repository-mingw: https://github.com/ocaml-opam/opam-repository-mingw.git#sunset
+            default: https://github.com/ocaml/opam-repository.git
+          opam-local-packages: |
+            haxe.opam
+          cache-prefix: w32-v1
+
+      # TODO make it work on first try
+      # (when cygwin cache doesn't exist, ocaml install fails with a curl error)
+      - name: Setup ocaml (second chance)
+        if: steps.ocaml.outcome == 'failure'
+        uses: kLabz/setup-ocaml@win32
+        with:
+          ocaml-compiler: 4.08.1
+          opam-depext: false
+          opam-repositories: |
+            opam-repository-mingw: https://github.com/ocaml-opam/opam-repository-mingw.git#sunset
+            default: https://github.com/ocaml/opam-repository.git
+          opam-local-packages: |
+            haxe.opam
+          cache-prefix: w32-v1
 
 
-      - name: Install OCaml
+      - name: Install dependencies
         shell: pwsh
         shell: pwsh
         run: |
         run: |
           Set-PSDebug -Trace 1
           Set-PSDebug -Trace 1
-          curl.exe -fsSL -o cygwin-setup.exe --retry 3 $($env:CYGWIN_SETUP)
-          Start-Process -FilePath "cygwin-setup.exe" -ArgumentList "-B -q -R $($env:CYG_ROOT) -l C:/tmp -s $($env:CYG_MIRROR) -P default -P make -P git -P zlib-devel -P rsync -P patch -P diffutils -P curl -P unzip -P tar -P m4 -P perl -P libpcre2-devel -P mbedtls-devel -P mingw64-$($env:MINGW_ARCH)-zlib -P mingw64-$($env:MINGW_ARCH)-gcc-core -P mingw64-$($env:MINGW_ARCH)-pcre2 --allow-unsupported-windows" -Wait -RedirectStandardOutput cygwin-setup-out.txt
-          Get-Content cygwin-setup-out.txt
-          & "$($env:CYG_ROOT)/bin/bash.exe" @('--norc', '--noprofile', '/etc/postinstall/ca-certificates.sh')
-          curl.exe -fsSL -o "opam.tar.xz" --retry 3 https://github.com/fdopen/opam-repository-mingw/releases/download/0.0.0.2/opam$($env:ARCH).tar.xz
           curl.exe -fsSL -o "libmbedtls.tar.xz" --retry 3 https://github.com/Simn/mingw64-mbedtls/releases/download/2.16.3/mingw64-$($env:MINGW_ARCH)-mbedtls-2.16.3-1.tar.xz
           curl.exe -fsSL -o "libmbedtls.tar.xz" --retry 3 https://github.com/Simn/mingw64-mbedtls/releases/download/2.16.3/mingw64-$($env:MINGW_ARCH)-mbedtls-2.16.3-1.tar.xz
           & "$($env:CYG_ROOT)/bin/bash.exe" @('-lc', 'curl -L https://cpanmin.us | perl - App::cpanminus')
           & "$($env:CYG_ROOT)/bin/bash.exe" @('-lc', 'curl -L https://cpanmin.us | perl - App::cpanminus')
           & "$($env:CYG_ROOT)/bin/bash.exe" @('-lc', 'cpanm IPC::System::Simple module')
           & "$($env:CYG_ROOT)/bin/bash.exe" @('-lc', 'cpanm IPC::System::Simple module')
           & "$($env:CYG_ROOT)/bin/bash.exe" @('-lc', 'cpanm String::ShellQuote')
           & "$($env:CYG_ROOT)/bin/bash.exe" @('-lc', 'cpanm String::ShellQuote')
           & "$($env:CYG_ROOT)/bin/bash.exe" @('-lc', 'echo "$OLDPWD"')
           & "$($env:CYG_ROOT)/bin/bash.exe" @('-lc', 'echo "$OLDPWD"')
           & "$($env:CYG_ROOT)/bin/bash.exe" @('-lc', 'cd "$OLDPWD" && tar -C / -xvf libmbedtls.tar.xz')
           & "$($env:CYG_ROOT)/bin/bash.exe" @('-lc', 'cd "$OLDPWD" && tar -C / -xvf libmbedtls.tar.xz')
-          & "$($env:CYG_ROOT)/bin/bash.exe" @('-lc', 'cd "$OLDPWD" && tar -xf opam.tar.xz')
-          & "$($env:CYG_ROOT)/bin/bash.exe" @('-lc', 'cd "$OLDPWD" && bash opam${ARCH}/install.sh')
 
 
       - name: Install OCaml libraries
       - name: Install OCaml libraries
-        if: steps.cache-opam.outputs.cache-hit != 'true'
         shell: pwsh
         shell: pwsh
         run: |
         run: |
           Set-PSDebug -Trace 1
           Set-PSDebug -Trace 1
-          & "$($env:CYG_ROOT)/bin/bash.exe" @('-lc', 'opam init mingw "https://github.com/fdopen/opam-repository-mingw.git#opam2" --comp 4.07.0+mingw${ARCH}c --switch 4.07.0+mingw${ARCH}c --auto-setup --yes 2>&1')
-          & "$($env:CYG_ROOT)/bin/bash.exe" @('-lc', 'opam update --yes 2>&1')
-          & "$($env:CYG_ROOT)/bin/bash.exe" @('-lc', 'cd "$OLDPWD" && opam pin add haxe . --kind=path --no-action --yes 2>&1')
-          & "$($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')
+          opam install haxe --deps-only
+          opam list
 
 
       - name: Expose mingw dll files
       - name: Expose mingw dll files
         shell: pwsh
         shell: pwsh
@@ -235,18 +240,29 @@ jobs:
           & "$($env:CYG_ROOT)/bin/bash.exe" @('-lc', 'cd "$OLDPWD" && cygcheck ./haxelib.exe')
           & "$($env:CYG_ROOT)/bin/bash.exe" @('-lc', 'cd "$OLDPWD" && cygcheck ./haxelib.exe')
           & "$($env:CYG_ROOT)/bin/bash.exe" @('-lc', 'cd "$OLDPWD" && ls ./out')
           & "$($env:CYG_ROOT)/bin/bash.exe" @('-lc', 'cd "$OLDPWD" && ls ./out')
 
 
+      - name: Check artifact
+        shell: bash
+        run: |
+          ls out
+          # Output should contain binaries zip, installer zip and nupkg
+          [ $(ls -1 out | wc -l) -eq "3" ]
+
       - name: Upload artifact
       - name: Upload artifact
-        uses: actions/[email protected]
+        uses: actions/upload-artifact@v3
         with:
         with:
           name: win${{env.ARCH}}Binaries
           name: win${{env.ARCH}}Binaries
           path: out
           path: out
 
 
 
 
   linux-build:
   linux-build:
-    runs-on: ubuntu-18.04
+    runs-on: ubuntu-20.04
     env:
     env:
       PLATFORM: linux64
       PLATFORM: linux64
       OPAMYES: 1
       OPAMYES: 1
+    strategy:
+      fail-fast: false
+      matrix:
+        ocaml: ["4.08.1", "5.0.0"]
     steps:
     steps:
       - uses: actions/checkout@main
       - uses: actions/checkout@main
         with:
         with:
@@ -257,7 +273,7 @@ jobs:
         uses: actions/[email protected]
         uses: actions/[email protected]
         with:
         with:
           path: ~/.opam/
           path: ~/.opam/
-          key: ${{ runner.os }}-${{ hashFiles('./opam', './libs/') }}-1
+          key: ${{ runner.os }}-${{ matrix.ocaml }}-${{ hashFiles('./haxe.opam', './libs/') }}
 
 
       - name: Install Neko from S3
       - name: Install Neko from S3
         run: |
         run: |
@@ -291,6 +307,7 @@ jobs:
           set -ex
           set -ex
           opam init # --disable-sandboxing
           opam init # --disable-sandboxing
           opam update
           opam update
+          opam switch create ${{ matrix.ocaml }}
           opam pin add haxe . --no-action
           opam pin add haxe . --no-action
           opam install haxe --deps-only --assume-depexts
           opam install haxe --deps-only --assume-depexts
           opam list
           opam list
@@ -315,9 +332,10 @@ jobs:
       - name: Extract branch name
       - name: Extract branch name
         id: extract_branch
         id: extract_branch
         shell: bash
         shell: bash
-        run: echo "##[set-output name=branch;]$(echo ${GITHUB_REF#refs/heads/})"
+        run: echo "branch=${GITHUB_REF#refs/heads/}" >> $GITHUB_OUTPUT
 
 
       - name: Build xmldoc
       - name: Build xmldoc
+        if: matrix.ocaml == '4.08.1'
         run: |
         run: |
           set -ex
           set -ex
           make -s xmldoc
           make -s xmldoc
@@ -329,20 +347,21 @@ jobs:
           EOL
           EOL
 
 
       - name: Upload artifact
       - name: Upload artifact
-        uses: actions/upload-artifact@v1.0.0
+        uses: actions/upload-artifact@v3
         with:
         with:
-          name: linuxBinaries
+          name: linuxBinaries${{ (matrix.ocaml == '5.0.0' && '_ocaml5') || '' }}
           path: out
           path: out
 
 
       - name: Upload xmldoc artifact
       - name: Upload xmldoc artifact
-        uses: actions/[email protected]
+        uses: actions/upload-artifact@v3
+        if: matrix.ocaml == '4.08.1'
         with:
         with:
           name: xmldoc
           name: xmldoc
           path: extra/doc
           path: extra/doc
 
 
   linux-test:
   linux-test:
     needs: linux-build
     needs: linux-build
-    runs-on: ubuntu-18.04
+    runs-on: ubuntu-20.04
     env:
     env:
       PLATFORM: linux64
       PLATFORM: linux64
       TEST: ${{matrix.target}}
       TEST: ${{matrix.target}}
@@ -351,6 +370,7 @@ jobs:
     strategy:
     strategy:
       fail-fast: false
       fail-fast: false
       matrix:
       matrix:
+        ocaml: ["4.08.1", "5.0.0"]
         target: [macro, js, hl, cpp, 'java,jvm', cs, php, python, lua, flash, neko]
         target: [macro, js, hl, cpp, 'java,jvm', cs, php, python, lua, flash, neko]
         include:
         include:
           - target: hl
           - target: hl
@@ -360,14 +380,15 @@ jobs:
           - target: lua
           - target: lua
             APT_PACKAGES: ncurses-dev
             APT_PACKAGES: ncurses-dev
           - target: flash
           - target: flash
-            APT_PACKAGES: libglib2.0-0 libfreetype6 xvfb
+            APT_PACKAGES: libglib2.0-0 libgtk2.0-0 libfreetype6 xvfb
     steps:
     steps:
       - uses: actions/checkout@main
       - uses: actions/checkout@main
         with:
         with:
           submodules: recursive
           submodules: recursive
-      - uses: actions/download-artifact@v1
+      - uses: actions/download-artifact@v3
         with:
         with:
-          name: linuxBinaries
+          name: linuxBinaries${{ (matrix.ocaml == '5.0.0' && '_ocaml5') || '' }}
+          path: linuxBinaries
 
 
       - name: Install Neko from S3
       - name: Install Neko from S3
         run: |
         run: |
@@ -425,7 +446,7 @@ jobs:
 
 
   test-docgen:
   test-docgen:
     needs: linux-build
     needs: linux-build
-    runs-on: ubuntu-18.04
+    runs-on: ubuntu-20.04
     env:
     env:
       PLATFORM: linux64
       PLATFORM: linux64
       HXCPP_COMPILE_CACHE: ~/hxcache
       HXCPP_COMPILE_CACHE: ~/hxcache
@@ -434,12 +455,13 @@ jobs:
         with:
         with:
           submodules: recursive
           submodules: recursive
 
 
-      - uses: actions/download-artifact@v1
+      - uses: actions/download-artifact@v3
         with:
         with:
           name: linuxBinaries
           name: linuxBinaries
+          path: linuxBinaries
 
 
       - name: Download xmldoc artifact
       - name: Download xmldoc artifact
-        uses: actions/download-artifact@v2
+        uses: actions/download-artifact@v3
         with:
         with:
           name: xmldoc
           name: xmldoc
           path: xmldoc
           path: xmldoc
@@ -501,14 +523,14 @@ jobs:
         working-directory: ${{github.workspace}}/tests/docgen
         working-directory: ${{github.workspace}}/tests/docgen
 
 
   linux-arm64:
   linux-arm64:
-    runs-on: ubuntu-18.04
+    runs-on: ubuntu-20.04
     permissions:
     permissions:
       packages: write
       packages: write
     env:
     env:
       FORCE_COLOR: 1
       FORCE_COLOR: 1
     steps:
     steps:
       - name: Login to GitHub Container Registry
       - name: Login to GitHub Container Registry
-        uses: docker/login-action@v1
+        uses: docker/login-action@v2
         with:
         with:
           registry: ghcr.io
           registry: ghcr.io
           username: ${{ github.actor }}
           username: ${{ github.actor }}
@@ -519,7 +541,7 @@ jobs:
 
 
       - name: Set up QEMU
       - name: Set up QEMU
         id: qemu
         id: qemu
-        uses: docker/setup-qemu-action@v1
+        uses: docker/setup-qemu-action@v2
         with:
         with:
             image: tonistiigi/binfmt:latest
             image: tonistiigi/binfmt:latest
             platforms: all
             platforms: all
@@ -551,7 +573,7 @@ jobs:
           EARTHLY_REMOTE_CACHE: "ghcr.io/${{env.CONTAINER_REG}}_cache:build-${{env.CONTAINER_TAG}}-arm64"
           EARTHLY_REMOTE_CACHE: "ghcr.io/${{env.CONTAINER_REG}}_cache:build-${{env.CONTAINER_TAG}}-arm64"
 
 
       - name: Upload artifact
       - name: Upload artifact
-        uses: actions/upload-artifact@v1.0.0
+        uses: actions/upload-artifact@v3
         with:
         with:
           name: linuxArm64Binaries
           name: linuxArm64Binaries
           path: out/linux/arm64
           path: out/linux/arm64
@@ -572,7 +594,7 @@ jobs:
         uses: actions/[email protected]
         uses: actions/[email protected]
         with:
         with:
           path: ~/.opam/
           path: ~/.opam/
-          key: ${{ runner.os }}-${{ hashFiles('./opam', './libs/') }}-1
+          key: ${{ runner.os }}-${{ hashFiles('./haxe.opam', './libs/') }}
 
 
       - name: Install Neko from S3
       - name: Install Neko from S3
         run: |
         run: |
@@ -594,8 +616,8 @@ jobs:
       - name: Install dependencies
       - name: Install dependencies
         env:
         env:
           # For compatibility with macOS 10.13
           # For compatibility with macOS 10.13
-          ZLIB_VERSION: 1.2.13
-          MBEDTLS_VERSION: 2.25.0
+          ZLIB_VERSION: 1.3
+          MBEDTLS_VERSION: 2.28.5
           PCRE2_VERSION: 10.42
           PCRE2_VERSION: 10.42
         run: |
         run: |
           set -ex
           set -ex
@@ -625,14 +647,13 @@ jobs:
           make && make install
           make && make install
           cd ..
           cd ..
 
 
-
       - name: Install OCaml libraries
       - name: Install OCaml libraries
         if: steps.cache-opam.outputs.cache-hit != 'true'
         if: steps.cache-opam.outputs.cache-hit != 'true'
         run: |
         run: |
           set -ex
           set -ex
           opam init # --disable-sandboxing
           opam init # --disable-sandboxing
           opam update
           opam update
-          opam switch create 4.07.1
+          opam switch create 4.08.1
           eval $(opam env)
           eval $(opam env)
           opam env
           opam env
           opam pin add ctypes 0.17.1 --yes
           opam pin add ctypes 0.17.1 --yes
@@ -657,7 +678,7 @@ jobs:
           otool -L ./haxelib
           otool -L ./haxelib
 
 
       - name: Upload artifact
       - name: Upload artifact
-        uses: actions/upload-artifact@v1.0.0
+        uses: actions/upload-artifact@v3
         with:
         with:
           name: macBinaries
           name: macBinaries
           path: out
           path: out
@@ -681,9 +702,10 @@ jobs:
       - uses: actions/checkout@main
       - uses: actions/checkout@main
         with:
         with:
           submodules: recursive
           submodules: recursive
-      - uses: actions/download-artifact@v1
+      - uses: actions/download-artifact@v3
         with:
         with:
           name: win${{env.ARCH}}Binaries
           name: win${{env.ARCH}}Binaries
+          path: win${{env.ARCH}}Binaries
 
 
       - name: Install Neko from S3
       - name: Install Neko from S3
         shell: pwsh
         shell: pwsh
@@ -697,6 +719,10 @@ jobs:
       - name: Print Neko version
       - name: Print Neko version
         run: neko -version 2>&1
         run: neko -version 2>&1
 
 
+      - uses: actions/setup-node@v3
+        with:
+          node-version: 18.17.1
+
       # - name: Quick test
       # - name: Quick test
       #   shell: pwsh
       #   shell: pwsh
       #   run: |
       #   run: |
@@ -773,9 +799,10 @@ jobs:
       - uses: actions/checkout@main
       - uses: actions/checkout@main
         with:
         with:
           submodules: recursive
           submodules: recursive
-      - uses: actions/download-artifact@v1
+      - uses: actions/download-artifact@v3
         with:
         with:
           name: win${{env.ARCH}}Binaries
           name: win${{env.ARCH}}Binaries
+          path: win${{env.ARCH}}Binaries
 
 
       - name: Install Neko from S3
       - name: Install Neko from S3
         shell: pwsh
         shell: pwsh
@@ -789,6 +816,10 @@ jobs:
       - name: Print Neko version
       - name: Print Neko version
         run: neko -version 2>&1
         run: neko -version 2>&1
 
 
+      - uses: actions/setup-node@v3
+        with:
+          node-version: 18.17.1
+
       # - name: Quick test
       # - name: Quick test
       #   shell: pwsh
       #   shell: pwsh
       #   run: |
       #   run: |
@@ -865,9 +896,10 @@ jobs:
       - uses: actions/checkout@main
       - uses: actions/checkout@main
         with:
         with:
           submodules: recursive
           submodules: recursive
-      - uses: actions/download-artifact@v1
+      - uses: actions/download-artifact@v3
         with:
         with:
           name: macBinaries
           name: macBinaries
+          path: macBinaries
 
 
       - name: Install Neko from S3
       - name: Install Neko from S3
         run: |
         run: |
@@ -923,7 +955,7 @@ jobs:
   deploy:
   deploy:
     if: success() && github.repository_owner == 'HaxeFoundation' && github.event_name != 'pull_request'
     if: success() && github.repository_owner == 'HaxeFoundation' && github.event_name != 'pull_request'
     needs: [linux-test, linux-arm64, mac-test, windows-test, windows64-test]
     needs: [linux-test, linux-arm64, mac-test, windows-test, windows64-test]
-    runs-on: ubuntu-18.04
+    runs-on: ubuntu-20.04
     steps:
     steps:
       # this is only needed for to get `COMMIT_DATE`...
       # this is only needed for to get `COMMIT_DATE`...
       # maybe https://github.community/t/expose-commit-timestamp-in-the-github-context-data/16460/3
       # maybe https://github.community/t/expose-commit-timestamp-in-the-github-context-data/16460/3
@@ -932,7 +964,7 @@ jobs:
         uses: actions/checkout@main
         uses: actions/checkout@main
 
 
       - name: Download build artifacts
       - name: Download build artifacts
-        uses: actions/download-artifact@v2
+        uses: actions/download-artifact@v3
 
 
       - name: Install awscli
       - name: Install awscli
         run: |
         run: |
@@ -944,7 +976,7 @@ jobs:
       - name: Extract branch name
       - name: Extract branch name
         id: extract_branch
         id: extract_branch
         shell: bash
         shell: bash
-        run: echo "##[set-output name=branch;]$(echo ${GITHUB_REF#refs/heads/})"
+        run: echo "branch=${GITHUB_REF#refs/heads/}" >> $GITHUB_OUTPUT
 
 
       - name: Upload binaries
       - name: Upload binaries
         shell: bash
         shell: bash
@@ -999,7 +1031,7 @@ jobs:
   deploy_apidoc:
   deploy_apidoc:
     if: success() && github.repository_owner == 'HaxeFoundation' && github.event_name != 'pull_request'
     if: success() && github.repository_owner == 'HaxeFoundation' && github.event_name != 'pull_request'
     needs: [linux-test, linux-arm64, mac-test, windows-test, windows64-test]
     needs: [linux-test, linux-arm64, mac-test, windows-test, windows64-test]
-    runs-on: ubuntu-18.04
+    runs-on: ubuntu-20.04
     steps:
     steps:
       - name: Install dependencies
       - name: Install dependencies
         run: |
         run: |
@@ -1007,7 +1039,7 @@ jobs:
           sudo apt-get install -qqy libc6
           sudo apt-get install -qqy libc6
 
 
       - name: Download Haxe
       - name: Download Haxe
-        uses: actions/download-artifact@v2
+        uses: actions/download-artifact@v3
         with:
         with:
           name: linuxBinaries
           name: linuxBinaries
           path: linuxBinaries
           path: linuxBinaries
@@ -1023,7 +1055,7 @@ jobs:
           sudo ln -s `pwd`/linuxBinaries/std /usr/local/share/haxe/std
           sudo ln -s `pwd`/linuxBinaries/std /usr/local/share/haxe/std
 
 
       - name: Download xmldoc artifact
       - name: Download xmldoc artifact
-        uses: actions/download-artifact@v2
+        uses: actions/download-artifact@v3
         with:
         with:
           name: xmldoc
           name: xmldoc
           path: xmldoc
           path: xmldoc

+ 4 - 0
.vscode/schemas/define.schema.json

@@ -61,6 +61,10 @@
 			"reserved": {
 			"reserved": {
 				"type": "boolean",
 				"type": "boolean",
 				"markdownDescription": "Reserved defines may not be defined from the command line."
 				"markdownDescription": "Reserved defines may not be defined from the command line."
+			},
+			"deprecated": {
+				"type": "string",
+				"markdownDescription": "Reason for the define to be deprecated."
 			}
 			}
 		},
 		},
 		"required": [
 		"required": [

+ 4 - 1
Earthfile

@@ -91,8 +91,11 @@ devcontainer:
     RUN git config --global codespaces-theme.hide-status 1
     RUN git config --global codespaces-theme.hide-status 1
 
 
     # Install OCaml libraries
     # Install OCaml libraries
-    COPY opam .
+    COPY haxe.opam .
     RUN opam init --disable-sandboxing
     RUN opam init --disable-sandboxing
+    RUN opam switch create 4.08.1
+    RUN eval $(opam env)
+    RUN opam env
     RUN opam install . --yes --deps-only --no-depexts
     RUN opam install . --yes --deps-only --no-depexts
     RUN opam list
     RUN opam list
     RUN ocamlopt -v
     RUN ocamlopt -v

+ 9 - 4
Makefile

@@ -59,6 +59,10 @@ PACKAGE_FILE_NAME=haxe_$(COMMIT_DATE)_$(COMMIT_SHA)
 HAXE_VERSION=$(shell $(CURDIR)/$(HAXE_OUTPUT) -version 2>&1 | awk '{print $$1;}')
 HAXE_VERSION=$(shell $(CURDIR)/$(HAXE_OUTPUT) -version 2>&1 | awk '{print $$1;}')
 HAXE_VERSION_SHORT=$(shell echo "$(HAXE_VERSION)" | grep -oE "^[0-9]+\.[0-9]+\.[0-9]+")
 HAXE_VERSION_SHORT=$(shell echo "$(HAXE_VERSION)" | grep -oE "^[0-9]+\.[0-9]+\.[0-9]+")
 
 
+NEKO_VERSION=2.3.0
+NEKO_MAJOR_VERSION=$(shell echo "$(NEKO_VERSION)" | grep -oE "^[0-9]+")
+NEKO_VERSION_TAG=v$(shell echo "$(NEKO_VERSION)" | sed "s/\./-/g")
+
 ifneq ($(STATICLINK),0)
 ifneq ($(STATICLINK),0)
 	LIB_PARAMS= -cclib '-Wl,-Bstatic -lpcre2-8 -lz -lmbedtls -lmbedx509 -lmbedcrypto -Wl,-Bdynamic '
 	LIB_PARAMS= -cclib '-Wl,-Bstatic -lpcre2-8 -lz -lmbedtls -lmbedx509 -lmbedcrypto -Wl,-Bdynamic '
 else
 else
@@ -165,7 +169,7 @@ $(INSTALLER_TMP_DIR):
 	mkdir -p $(INSTALLER_TMP_DIR)
 	mkdir -p $(INSTALLER_TMP_DIR)
 
 
 $(INSTALLER_TMP_DIR)/neko-osx64.tar.gz: $(INSTALLER_TMP_DIR)
 $(INSTALLER_TMP_DIR)/neko-osx64.tar.gz: $(INSTALLER_TMP_DIR)
-	wget -nv https://github.com/HaxeFoundation/neko/releases/download/v2-3-0/neko-2.3.0-osx64.tar.gz -O installer/neko-osx64.tar.gz
+	wget -nv https://github.com/HaxeFoundation/neko/releases/download/$(NEKO_VERSION_TAG)/neko-$(NEKO_VERSION)-osx64.tar.gz -O installer/neko-osx64.tar.gz
 
 
 # Installer
 # Installer
 
 
@@ -173,7 +177,6 @@ package_installer_mac: $(INSTALLER_TMP_DIR)/neko-osx64.tar.gz package_unix
 	$(eval OUTFILE := $(shell pwd)/$(PACKAGE_OUT_DIR)/$(PACKAGE_FILE_NAME)_installer.tar.gz)
 	$(eval OUTFILE := $(shell pwd)/$(PACKAGE_OUT_DIR)/$(PACKAGE_FILE_NAME)_installer.tar.gz)
 	$(eval PACKFILE := $(shell pwd)/$(PACKAGE_OUT_DIR)/$(PACKAGE_FILE_NAME)_bin.tar.gz)
 	$(eval PACKFILE := $(shell pwd)/$(PACKAGE_OUT_DIR)/$(PACKAGE_FILE_NAME)_bin.tar.gz)
 	$(eval VERSION := $(shell $(CURDIR)/$(HAXE_OUTPUT) -version 2>&1))
 	$(eval VERSION := $(shell $(CURDIR)/$(HAXE_OUTPUT) -version 2>&1))
-	$(eval NEKOVER := $(shell neko -version 2>&1))
 	bash -c "rm -rf $(INSTALLER_TMP_DIR)/{resources,pkg,tgz,haxe.tar.gz}"
 	bash -c "rm -rf $(INSTALLER_TMP_DIR)/{resources,pkg,tgz,haxe.tar.gz}"
 	mkdir $(INSTALLER_TMP_DIR)/resources
 	mkdir $(INSTALLER_TMP_DIR)/resources
 	# neko - unpack to change the dir name
 	# neko - unpack to change the dir name
@@ -186,6 +189,8 @@ package_installer_mac: $(INSTALLER_TMP_DIR)/neko-osx64.tar.gz package_unix
 	cd $(INSTALLER_TMP_DIR)/resources && tar -zcvf haxe.tar.gz haxe
 	cd $(INSTALLER_TMP_DIR)/resources && tar -zcvf haxe.tar.gz haxe
 	# scripts
 	# scripts
 	cp -rf extra/mac-installer/* $(INSTALLER_TMP_DIR)/resources
 	cp -rf extra/mac-installer/* $(INSTALLER_TMP_DIR)/resources
+	sed -i '' 's/%%NEKO_VERSION%%/$(NEKO_VERSION)/g' $(INSTALLER_TMP_DIR)/resources/scripts/neko-postinstall.sh
+	sed -i '' 's/%%NEKO_MAJOR_VERSION%%/$(NEKO_MAJOR_VERSION)/g' $(INSTALLER_TMP_DIR)/resources/scripts/neko-postinstall.sh
 	cd $(INSTALLER_TMP_DIR)/resources && tar -zcvf scripts.tar.gz scripts
 	cd $(INSTALLER_TMP_DIR)/resources && tar -zcvf scripts.tar.gz scripts
 	# installer structure
 	# installer structure
 	mkdir -p $(INSTALLER_TMP_DIR)/pkg
 	mkdir -p $(INSTALLER_TMP_DIR)/pkg
@@ -201,12 +206,12 @@ package_installer_mac: $(INSTALLER_TMP_DIR)/neko-osx64.tar.gz package_unix
 	sed -i '' 's/%%VERSION%%/$(VERSION)/g' PackageInfo ;\
 	sed -i '' 's/%%VERSION%%/$(VERSION)/g' PackageInfo ;\
 	sed -i '' 's/%%VERSTRING%%/$(VERSION)/g' PackageInfo ;\
 	sed -i '' 's/%%VERSTRING%%/$(VERSION)/g' PackageInfo ;\
 	sed -i '' 's/%%VERLONG%%/$(VERSION)/g' PackageInfo ;\
 	sed -i '' 's/%%VERLONG%%/$(VERSION)/g' PackageInfo ;\
-	sed -i '' 's/%%NEKOVER%%/$(NEKOVER)/g' PackageInfo ;\
+	sed -i '' 's/%%NEKOVER%%/$(NEKO_VERSION)/g' PackageInfo ;\
 	cd .. ;\
 	cd .. ;\
 	sed -i '' 's/%%VERSION%%/$(VERSION)/g' Distribution ;\
 	sed -i '' 's/%%VERSION%%/$(VERSION)/g' Distribution ;\
 	sed -i '' 's/%%VERSTRING%%/$(VERSION)/g' Distribution ;\
 	sed -i '' 's/%%VERSTRING%%/$(VERSION)/g' Distribution ;\
 	sed -i '' 's/%%VERLONG%%/$(VERSION)/g' Distribution ;\
 	sed -i '' 's/%%VERLONG%%/$(VERSION)/g' Distribution ;\
-	sed -i '' 's/%%NEKOVER%%/$(NEKOVER)/g' Distribution ;\
+	sed -i '' 's/%%NEKOVER%%/$(NEKO_VERSION)/g' Distribution ;\
 	sed -i '' 's/%%INSTKB%%/$$INSTKBH/g' Distribution"
 	sed -i '' 's/%%INSTKB%%/$$INSTKBH/g' Distribution"
 	# repackage
 	# repackage
 	cd $(INSTALLER_TMP_DIR)/pkg; xar --compression none -cf ../$(PACKAGE_FILE_NAME).pkg *
 	cd $(INSTALLER_TMP_DIR)/pkg; xar --compression none -cf ../$(PACKAGE_FILE_NAME).pkg *

+ 5 - 2
Makefile.win

@@ -75,13 +75,15 @@ package_choco:
 	mkdir -p OUTPUT
 	mkdir -p OUTPUT
 	7z x -y out/$(PACKAGE_FILE_NAME)_bin.zip -oout > log.txt || type log.txt
 	7z x -y out/$(PACKAGE_FILE_NAME)_bin.zip -oout > log.txt || type log.txt
 	mv out/$(PACKAGE_FILE_NAME) out/choco
 	mv out/$(PACKAGE_FILE_NAME) out/choco
-	sed -e 's/@SNAPSHOT_VERSION@/$(HAXE_VERSION_SHORT)-SNAP$(COMMIT_DATE)/g' extra/choco/haxe.nuspec > out/choco/haxe.nuspec
+	cp extra/choco/haxe.nuspec out/choco/haxe.nuspec
+	sed -i 's/@SNAPSHOT_VERSION@/$(HAXE_VERSION_SHORT)-SNAP$(COMMIT_DATE)/g' out/choco/haxe.nuspec
+	sed -i 's/@NEKO_VERSION@/$(NEKO_VERSION)/g' out/choco/haxe.nuspec
 	cd out/choco && choco pack
 	cd out/choco && choco pack
 	mv out/choco/haxe.*.nupkg out
 	mv out/choco/haxe.*.nupkg out
 	rm -rf out/choco
 	rm -rf out/choco
 
 
 $(INSTALLER_TMP_DIR)/neko-win.zip: $(INSTALLER_TMP_DIR)
 $(INSTALLER_TMP_DIR)/neko-win.zip: $(INSTALLER_TMP_DIR)
-	wget -nv https://github.com/HaxeFoundation/neko/releases/download/v2-3-0/neko-2.3.0-win$(NEKO_ARCH_STR).zip -O installer/neko-win.zip
+	curl -L https://github.com/HaxeFoundation/neko/releases/download/$(NEKO_VERSION_TAG)/neko-$(NEKO_VERSION)-win$(NEKO_ARCH_STR).zip -o installer/neko-win.zip
 
 
 package_installer_win: $(INSTALLER_TMP_DIR)/neko-win.zip package_win
 package_installer_win: $(INSTALLER_TMP_DIR)/neko-win.zip package_win
 	$(eval OUTFILE := $(PACKAGE_OUT_DIR)/$(PACKAGE_FILE_NAME)_installer.zip)
 	$(eval OUTFILE := $(PACKAGE_OUT_DIR)/$(PACKAGE_FILE_NAME)_installer.zip)
@@ -104,6 +106,7 @@ package_installer_win: $(INSTALLER_TMP_DIR)/neko-win.zip package_win
 	sed -i "s/%%VERSION%%/$(HAXE_VERSION_SHORT)/g" $(INSTALLER_TMP_DIR)/installer.nsi
 	sed -i "s/%%VERSION%%/$(HAXE_VERSION_SHORT)/g" $(INSTALLER_TMP_DIR)/installer.nsi
 	sed -i "s/%%VERSTRING%%/$(HAXE_VERSION)/g" $(INSTALLER_TMP_DIR)/installer.nsi
 	sed -i "s/%%VERSTRING%%/$(HAXE_VERSION)/g" $(INSTALLER_TMP_DIR)/installer.nsi
 	sed -i "s/%%VERLONG%%/$(HAXE_VERSION)/g" $(INSTALLER_TMP_DIR)/installer.nsi
 	sed -i "s/%%VERLONG%%/$(HAXE_VERSION)/g" $(INSTALLER_TMP_DIR)/installer.nsi
+	sed -i "s/%%NEKO_VERSION%%/$(NEKO_VERSION)/g" $(INSTALLER_TMP_DIR)/installer.nsi
 	cd $(INSTALLER_TMP_DIR) && makensis installer.nsi
 	cd $(INSTALLER_TMP_DIR) && makensis installer.nsi
 	7z a -r -tzip $(OUTFILE) $(INSTALLER_TMP_DIR)/*.exe
 	7z a -r -tzip $(OUTFILE) $(INSTALLER_TMP_DIR)/*.exe
 	dir $(PACKAGE_OUT_DIR)
 	dir $(PACKAGE_OUT_DIR)

+ 2 - 1
dune

@@ -1 +1,2 @@
-(data_only_dirs extra lib std tests)
+(dirs :standard \ tests std extra)
+(data_only_dirs lib)

+ 1 - 1
extra/BUILDING.md

@@ -36,7 +36,7 @@ You need to install some native libraries as well as some OCaml libraries.
 To install the native libraries, use the appropriate system package manager.
 To install the native libraries, use the appropriate system package manager.
 
 
  * Mac OS X
  * Mac OS X
-    * Use [Homebrew](https://brew.sh/), `brew install zlib pcre2`.
+    * Use [Homebrew](https://brew.sh/), `brew install zlib pcre2 mbedtls@2`.
  * Debian / Ubuntu
  * Debian / Ubuntu
     * `sudo apt install libpcre2-dev zlib1g-dev libmbedtls-dev`.
     * `sudo apt install libpcre2-dev zlib1g-dev libmbedtls-dev`.
  * Windows (Cygwin)
  * Windows (Cygwin)

+ 180 - 5
extra/CHANGES.txt

@@ -1,9 +1,184 @@
-2022-xx-xx 4.3.0
+2023-09-17 4.3.3
 
 
 	General improvements:
 	General improvements:
 
 
+	all : improve extra field error range (#11335)
+	all : better error messages for --connect
+	hl : improve error message when hl_version is missing (#11086)
+	hl/c : compiler now adds hlc define when targeting hl/c (#11382)
+	macro : update macro API restriction warnings when using -D haxe-next (#11377)
+
+	Bugfixes:
+
+	all : handle non existing files for positions in pretty errors (#11364)
+	all : metadata support for local static vars
+	all : catch trailing invalid syntax in string interpolation (#10287)
+	eval : fix Array.resize retaining values (#11317)
+	eval/hl : fix catching haxe.ValueException (#11321)
+	hl : make genhl respect Meta.NoExpr (#11257)
+	hl : don't add bindings for non existing methods
+	hl/c : add missing I64 mod support
+	hl/c : rework reserved keywords (#11293, #11378)
+	hl/c : fix Int64 unsigned right shift overflow (#11382)
+	java/cs: fix stack overflow from closures constraints (#11350)
+	js : DOMElement insertAdjacentElement should not be pure (#11333)
+	macro : catch trailing invalid syntax in Context.parseInlineString (#11368)
+	macro : fix TDAbstract without flags in haxe.macro.Printer
+
+2023-09-01 4.3.2
+
+	General improvements:
+
+	all : do not raise error on no-op reification outside macro
+
+	Bugfixes:
+
+	all : don't infer Null<?> if it already is Null<?> (#11286)
+	all : fix ?? inference and precedence (#11252)
+	all : bring back forced inline (#11217)
+	all : allow non constant "inline" var init with -D no-inline (#11192)
+	all : improve @:enum abstract deprecation warning handling (#11302)
+	all : fix some stack overflow with pretty errors
+	display : fix go to definition with final (#11173)
+	display : fix completion requests with @:forwardStatics (#11294)
+	eval : fix MainLoop.add not repeating (#11202)
+	hl/eval/neko : fix exception stack when wrapping native exceptions (#11249)
+	macro : map `this` when restoring typed expressions (#11212)
+	macro : safe navigation fix for ExprTools.map (#11204)
+	macro : safe navigation fix for haxe.macro.Printer (#11206)
+	macro : macro generated EVars position fixes (#11163)
+	macro : fix abstract casts for local statics (#11301)
+	macro : add flags to TDAbstract to be able to construct enum abstracts (#11230)
+	nullsafety : make break/continue expressions not-nullable (#11269)
+	nullsafety : handle return in assignment (#11114)
+
+2023-04-28 4.3.1
+
+	Breaking changes:
+
+	all : namespace message reporting defines (#11142)
+
+	General improvements:
+
+	all : support deprecation for defines
+
+	Bugfixes:
+
+	all : fix --times with compilation server (#11091)
+	all : fix default type parameters not respecting imports (#11161)
+	all : fix bytecode bindings issues (#11098)
+	macro : allow local statics in macro functions (#11096)
+	cpp : fix AtomicInt warnings on cppia (#11105)
+	cpp : fix deprecated implicit casts of cpp.Int64 (#10998)
+	cpp : add white space around template type syntax (#11107)
+	java : don't check native signatures on extern functions (#11131)
+	lua : remove non existent luautf8 charCodeAt extern (#11097)
+
+2023-04-06 4.3.0
+
+	New features:
+
+	all : support defaults for type parameters (#10518)
+	all : support @:op(a()) on abstracts (#10119)
+	all : support abstract keyword to reference the abstract (#10513)
+	all : support static var at expression-level (#10555)
+	all : support ?. safe navigation operator (#10561)
+	all : added ?? null coalescing operator (#10428)
+	all : add -w compiler option to configure warnings (#10612)
+	all : added new error reporting modes (#10863)
+	all : support custom metadata and defines (#10858)
+
+	General improvements:
+
+	all : made various optimizations in the analyzer
+	all : made various improvements to diagnostics
+	all : made various improvements to null-safety
 	all : optimize `.bind` for instance methods (#10737)
 	all : optimize `.bind` for instance methods (#10737)
-	lua : add lua-standalone global compiler flag (#10979)
+	all : improved various parser error messages
+	all : improved compilation server performance
+	all : improved code generation for try/catch (#10519)
+	all : infer property accessor type from the property (#10569)
+	all : improved inference of local functions typed against abstracts (#10336)
+	all : improved completion on module-level fields
+	all : improved handling of native libraries on the compilation server
+	all : improved performance when generating locals (#10648)
+	all : made Std.parseInt more consistent across targets (#10664)
+	all : infer null literals as Null<?> (#7736)
+	all : made field access errors more consistent (#10896)
+	all : consistently allow trailing commas (#11009)
+	all : migrated all relevant targets to PCRE2 (#10491)
+	all : made analyzer reconstruct do-while loops (#7979)
+	all : improved restrictions on init macros (#11043)
+	all : improved positions of @:structInit fields (#9318)
+	macro : support map literals in Context.makeExpr (#10259)
+	macro : added haxe.macro.Compiler.getConfiguration() (#10871)
+	macro : added withImports and withOption to haxe.macro.Context
+	macro : added getMacroStack and onAfterInitMacros to haxe.macro.Context (#11043)
+	macro : added haxe.macro.Context.makeMonomorph (#10728)
+	eval : added dictionary mode to objects, increasing performance in some cases (#10284)
+	eval : fixed Sys.exit handling messing up the compilation server (#10642)
+	eval : added -D eval-print-depth and -D eval-pretty-print (#10952, #10963)
+	cpp : supported type parameters on extern classes (#10415)
+	cpp : haxe.Int64 improvements (#9935)
+	cpp : non-blocking process exit code reading (#10321)
+	js : improved type names for debugger (#10894)
+	lua : added SSL implementation (#10593)
+	lua : fixed String API when -D no-inline was in place (#11057)
+	lua : non-zero exit code in case of uncaught exception (#11082)
+	java : deal with default implementations when loading extern libraries (#10466)
+	jvm : improved closure naming (#10571)
+	jvm : supported --jvm dir (#10614)
+	jvm : added some missing TShort and TFloat handling (#10722)
+	jvm : added experimental support for functional interfaces (#11019)
+	php : added and fixed several extern functions
+
+	Standard Library:
+
+	all : added atomic operations to several targets (#10610)
+	all : added Vector.fill (#10687)
+	sys : added sys.thread.Condition and Semaphore (#10503)
+	sys : added Http.getResponseHeaderValues to deal with multiple values of same key (#10812)
+	sys : make Sys.environment consistent between targets (#10460)
+	sys : consistent way to unset environment variables with Sys.putEnv (#10402)
+
+	Bugfixes:
+
+	all : properly disallowed macro reification in invalid places (#10883)
+	all : fixed behavior when extending abstract classes with final fields (#10139)
+	all : addressed some issues with constructor inlining (#10304)
+	all : fixed pattern matcher bug related to null-guards (#10291)
+	all : fixed weird parser behavior on first offset in files (#10322)
+	all : fixed various issues related to the final modifier
+	all : fixed various issues related to overload handling
+	all : fixed precedence of => vs. ?: (#10455)
+	all : made error positions in structure declarations more accurate (#9584)
+	all : brought back proper check when accessing super fields (#10521)
+	all : fixed @:publicFields on abstracts (#10541)
+	all : inherited some metadata to @:generic implementation classes (#10557)
+	all : fixed various problems in EventLoop and MainLoop
+	all : fixed infinite recursion from invalid inheritance (#10245)
+	all : fixed strange interaction between static extensions and macro functions (#10587)
+	all : fixed problems with @:generic on the compilation server (#10635)
+	all : fixed Context.onTypeNotFound being called multiple times for the same thing (#10678)
+	all : fixed type parameter problem involving abstract classes and interfaces (#10748)
+	all : fixed #if (a != b) yielding true for nonexistent values (#10868)
+	all : fixed interaction between @:generic and abstract class (#10735)
+	all : fixed @:using loading types too eagerly (#10107)
+	all : fixed parser ignoring subsequent documentation comments (#10171)
+	all : fixed parser function messing up unrelated file state in some cases (#10763)
+	all : unified Map printing to always use [] (#9260)
+	cpp : fixed problem with cpp.Pointer being used in enum arguments (#10831)
+	macro : improved handling of macro this expressions (#10793)
+	eval : fixed bit shift operations > 31 (#10752)
+	eval : fixed Bytes.toString causing an internal exception (#10623)
+	jvm : fixed @:native processing (#10280)
+	jvm : fixed Type.getEnumConstructs on native enums (#10508)
+	jvm : fixed @:volatile being ignored (#10594)
+	jvm : fixed some hashing issue when pattern matching on emojis (#10720)
+	jvm : fixed stack handling on return return (#10743)
+	hl : fixed various code generation problems
+	python : fixed SslSocket for newer python versions (#8401)
+	python : fixed syntax issue related to Vector (#11060)
 
 
 2021-03-06 4.2.5:
 2021-03-06 4.2.5:
 
 
@@ -941,7 +1116,7 @@
 	Bugfixes:
 	Bugfixes:
 
 
 	php7: fix Reflect.field() for strings (#6276)
 	php7: fix Reflect.field() for strings (#6276)
-	php7: fix `@:enum abstract` generation  without `-dce full` (#6175)
+	php7: fix `@:enum abstract` generation without `-dce full` (#6175)
 	php7: fix using enum constructor with arguments as a call argument (#6177)
 	php7: fix using enum constructor with arguments as a call argument (#6177)
 	php7: fix `null` property access (#6281)
 	php7: fix `null` property access (#6281)
 	php7: fix setting values in a map stored in another map (#6257)
 	php7: fix setting values in a map stored in another map (#6257)
@@ -987,7 +1162,7 @@
 
 
 	all : fixed DCE issue with interface fields (#6502)
 	all : fixed DCE issue with interface fields (#6502)
 	cpp : fixed return typing for embedded closures (#6121)
 	cpp : fixed return typing for embedded closures (#6121)
-	php7: fixed `@:enum abstract` generation  without `-dce full` (#6175)
+	php7: fixed `@:enum abstract` generation without `-dce full` (#6175)
 	php7: fixed using enum constructor with arguments as a call argument (#6177)
 	php7: fixed using enum constructor with arguments as a call argument (#6177)
 	php7: fixed accessing methods on dynamic values (#6211)
 	php7: fixed accessing methods on dynamic values (#6211)
 	php7: fixed `null` property access (#6281)
 	php7: fixed `null` property access (#6281)
@@ -1703,7 +1878,7 @@
 	all : allow to access root package with std prefix (std.Type for example)
 	all : allow to access root package with std prefix (std.Type for example)
 	all : added haxe.EnumFlags
 	all : added haxe.EnumFlags
 	sys : io.File.getChar/stdin/stdout/stderr are now in Sys class
 	sys : io.File.getChar/stdin/stdout/stderr are now in Sys class
-	cpp : Reflect.getField and Reflect.setField no longer call property functions.  Use Reflect.getProperty and Refelect.setProperty instead.
+	cpp : Reflect.getField and Reflect.setField no longer call property functions. Use Reflect.getProperty and Refelect.setProperty instead.
 	cpp : Default arguments now use Null<T> for performance increase and interface compatibility
 	cpp : Default arguments now use Null<T> for performance increase and interface compatibility
 	cpp : Added metadata options for injecting native cpp code into headers, classes and functions
 	cpp : Added metadata options for injecting native cpp code into headers, classes and functions
 	php : added php.Lib.mail
 	php : added php.Lib.mail

+ 1 - 1
extra/EnvVarUpdate.nsh

@@ -43,7 +43,7 @@
   !ifndef Un${StrFuncName}_INCLUDED
   !ifndef Un${StrFuncName}_INCLUDED
     ${Un${StrFuncName}}
     ${Un${StrFuncName}}
   !endif
   !endif
-  !define un.${StrFuncName} "${Un${StrFuncName}}"
+  !define un.${StrFuncName} '${Un${StrFuncName}}'
 !macroend
 !macroend
 
 
 !insertmacro _IncludeStrFunction StrTok
 !insertmacro _IncludeStrFunction StrTok

+ 37 - 38
extra/ImportAll.hx

@@ -26,7 +26,7 @@ class ImportAll {
 	static function isSysTarget() {
 	static function isSysTarget() {
 		return Context.defined("neko") || Context.defined("php") || Context.defined("cpp") ||
 		return Context.defined("neko") || Context.defined("php") || Context.defined("cpp") ||
 		       Context.defined("java") || Context.defined("python") ||
 		       Context.defined("java") || Context.defined("python") ||
-		       Context.defined("lua") || Context.defined("hl") || Context.defined("eval"); // TODO: have to add cs here, SPOD gets in the way at the moment
+		       Context.defined("lua") || Context.defined("hl") || Context.defined("eval");
 	}
 	}
 
 
 	public static function run( ?pack ) {
 	public static function run( ?pack ) {
@@ -34,9 +34,6 @@ class ImportAll {
 			pack = "";
 			pack = "";
 			haxe.macro.Compiler.define("doc_gen");
 			haxe.macro.Compiler.define("doc_gen");
 		}
 		}
-		if (Context.defined("interp")) {
-			haxe.macro.Compiler.define("macro");
-		}
 		switch( pack ) {
 		switch( pack ) {
 		case "php":
 		case "php":
 			if( !Context.defined("php") ) return;
 			if( !Context.defined("php") ) return;
@@ -72,42 +69,44 @@ class ImportAll {
 			if (!Context.defined("neko") && !Context.defined("cpp")) return;
 			if (!Context.defined("neko") && !Context.defined("cpp")) return;
 		case "tools", "build-tool", "jar-tool": return;
 		case "tools", "build-tool", "jar-tool": return;
 		}
 		}
-		for( p in Context.getClassPath() ) {
-			if( p == "/" || p == "" )
-				continue;
-			// skip if we have a classpath to haxe
-			if( pack.length == 0 && sys.FileSystem.exists(p+"std") )
-				continue;
-			var p = p + pack.split(".").join("/");
-			if( StringTools.endsWith(p,"/") )
-				p = p.substr(0,-1);
-			if( !sys.FileSystem.exists(p) || !sys.FileSystem.isDirectory(p) )
-				continue;
-			for( file in sys.FileSystem.readDirectory(p) ) {
-				if( file == ".svn" || file == "_std" )
+		Context.onAfterInitMacros(() -> {
+			for( p in Context.getClassPath() ) {
+				if( p == "/" || p == "" )
+					continue;
+				// skip if we have a classpath to haxe
+				if( pack.length == 0 && sys.FileSystem.exists(p+"std") )
 					continue;
 					continue;
-				var full = (pack == "") ? file : pack + "." + file;
-				if( StringTools.endsWith(file, ".hx") && file.substr(0, file.length - 3).indexOf(".") < 0 ) {
-					var cl = full.substr(0, full.length - 3);
-					switch( cl ) {
-					case "ImportAll", "neko.db.MacroManager": continue;
-					case "haxe.TimerQueue": if( Context.defined("neko") || Context.defined("php") || Context.defined("cpp") ) continue;
-					case "Sys": if(!isSysTarget()) continue;
-					case "haxe.web.Request": if( !(Context.defined("neko") || Context.defined("php") || Context.defined("js")) ) continue;
-					case "haxe.macro.ExampleJSGenerator","haxe.macro.Context", "haxe.macro.Compiler": if( !Context.defined("eval") ) continue;
-					case "haxe.remoting.SocketWrapper": if( !Context.defined("flash") ) continue;
-					case "haxe.remoting.SyncSocketConnection": if( !(Context.defined("neko") || Context.defined("php") || Context.defined("cpp")) ) continue;
-					case "neko.vm.Ui" | "sys.db.Sqlite" | "sys.db.Mysql" if ( Context.defined("interp") ): continue;
-					case "sys.db.Sqlite" | "sys.db.Mysql" | "cs.db.AdoNet" if ( Context.defined("cs") ): continue;
-					case "haxe.atomic.AtomicBool" if(!Context.defined("target.atomics")): continue;
-					case "haxe.atomic.AtomicInt" if(!Context.defined("target.atomics")): continue;
-					case "haxe.atomic.AtomicObject" if(!Context.defined("target.atomics") || Context.defined("js") || Context.defined("cpp")): continue;
-					}
-					Context.getModule(cl);
-				} else if( sys.FileSystem.isDirectory(p + "/" + file) )
-					run(full);
+				var p = p + pack.split(".").join("/");
+				if( StringTools.endsWith(p,"/") )
+					p = p.substr(0,-1);
+				if( !sys.FileSystem.exists(p) || !sys.FileSystem.isDirectory(p) )
+					continue;
+				for( file in sys.FileSystem.readDirectory(p) ) {
+					if( file == ".svn" || file == "_std" )
+						continue;
+					var full = (pack == "") ? file : pack + "." + file;
+					if( StringTools.endsWith(file, ".hx") && file.substr(0, file.length - 3).indexOf(".") < 0 ) {
+						var cl = full.substr(0, full.length - 3);
+						switch( cl ) {
+						case "ImportAll", "neko.db.MacroManager": continue;
+						case "haxe.TimerQueue": if( Context.defined("neko") || Context.defined("php") || Context.defined("cpp") ) continue;
+						case "Sys": if(!isSysTarget()) continue;
+						case "haxe.web.Request": if( !(Context.defined("neko") || Context.defined("php") || Context.defined("js")) ) continue;
+						case "haxe.macro.ExampleJSGenerator","haxe.macro.Context", "haxe.macro.Compiler": if( !Context.defined("eval") ) continue;
+						case "haxe.remoting.SocketWrapper": if( !Context.defined("flash") ) continue;
+						case "haxe.remoting.SyncSocketConnection": if( !(Context.defined("neko") || Context.defined("php") || Context.defined("cpp")) ) continue;
+						case "neko.vm.Ui" | "sys.db.Sqlite" | "sys.db.Mysql" if ( Context.defined("interp") ): continue;
+						case "sys.db.Sqlite" | "sys.db.Mysql" | "cs.db.AdoNet" if ( Context.defined("cs") ): continue;
+						case "haxe.atomic.AtomicBool" if(!Context.defined("target.atomics")): continue;
+						case "haxe.atomic.AtomicInt" if(!Context.defined("target.atomics")): continue;
+						case "haxe.atomic.AtomicObject" if(!Context.defined("target.atomics") || Context.defined("js") || Context.defined("cpp")): continue;
+						}
+						Context.getModule(cl);
+					} else if( sys.FileSystem.isDirectory(p + "/" + file) )
+						run(full);
+				}
 			}
 			}
-		}
+		});
 	}
 	}
 
 
 }
 }

+ 3 - 3
extra/choco/haxe.nuspec

@@ -17,12 +17,12 @@
         <requireLicenseAcceptance>false</requireLicenseAcceptance>
         <requireLicenseAcceptance>false</requireLicenseAcceptance>
         <summary>Haxe is an open source toolkit based on a modern, high level, strictly typed programming language, a cross-compiler, a complete cross-platform standard library and ways to access each platform's native capabilities.</summary>
         <summary>Haxe is an open source toolkit based on a modern, high level, strictly typed programming language, a cross-compiler, a complete cross-platform standard library and ways to access each platform's native capabilities.</summary>
         <description>Haxe is an open source toolkit based on a modern, high level, strictly typed programming language, a cross-compiler, a complete cross-platform standard library and ways to access each platform's native capabilities.
         <description>Haxe is an open source toolkit based on a modern, high level, strictly typed programming language, a cross-compiler, a complete cross-platform standard library and ways to access each platform's native capabilities.
- 
+
 This package will install haxe and haxelib. After installation, you should run `haxelib setup %path%;`, where `%path%` is the haxelib repository folder for placing third-party libraries. The folder should be created manually before running the command.</description>
 This package will install haxe and haxelib. After installation, you should run `haxelib setup %path%;`, where `%path%` is the haxelib repository folder for placing third-party libraries. The folder should be created manually before running the command.</description>
         <releaseNotes>https://github.com/HaxeFoundation/haxe/blob/master/extra/CHANGES.txt</releaseNotes>
         <releaseNotes>https://github.com/HaxeFoundation/haxe/blob/master/extra/CHANGES.txt</releaseNotes>
         <tags>haxe programming development foss cross-platform</tags>
         <tags>haxe programming development foss cross-platform</tags>
         <dependencies>
         <dependencies>
-            <dependency id="neko" version="2.1.0" />
+            <dependency id="neko" version="@NEKO_VERSION@" />
         </dependencies>
         </dependencies>
     </metadata>
     </metadata>
-</package>
+</package>

+ 4 - 5
extra/github-actions/build-mac.yml

@@ -1,8 +1,8 @@
 - name: Install dependencies
 - name: Install dependencies
   env:
   env:
     # For compatibility with macOS 10.13
     # For compatibility with macOS 10.13
-    ZLIB_VERSION: 1.2.13
-    MBEDTLS_VERSION: 2.25.0
+    ZLIB_VERSION: 1.3
+    MBEDTLS_VERSION: 2.28.5
     PCRE2_VERSION: 10.42
     PCRE2_VERSION: 10.42
   run: |
   run: |
     set -ex
     set -ex
@@ -32,14 +32,13 @@
     make && make install
     make && make install
     cd ..
     cd ..
 
 
-
 - name: Install OCaml libraries
 - name: Install OCaml libraries
   if: steps.cache-opam.outputs.cache-hit != 'true'
   if: steps.cache-opam.outputs.cache-hit != 'true'
   run: |
   run: |
     set -ex
     set -ex
     opam init # --disable-sandboxing
     opam init # --disable-sandboxing
     opam update
     opam update
-    opam switch create 4.07.1
+    opam switch create 4.08.1
     eval $(opam env)
     eval $(opam env)
     opam env
     opam env
     opam pin add ctypes 0.17.1 --yes
     opam pin add ctypes 0.17.1 --yes
@@ -64,7 +63,7 @@
     otool -L ./haxelib
     otool -L ./haxelib
 
 
 - name: Upload artifact
 - name: Upload artifact
-  uses: actions/upload-artifact@v1.0.0
+  uses: actions/upload-artifact@v3
   with:
   with:
     name: macBinaries
     name: macBinaries
     path: out
     path: out

+ 8 - 1
extra/github-actions/build-windows.yml

@@ -26,8 +26,15 @@
     & "$($env:CYG_ROOT)/bin/bash.exe" @('-lc', 'cd "$OLDPWD" && cygcheck ./haxelib.exe')
     & "$($env:CYG_ROOT)/bin/bash.exe" @('-lc', 'cd "$OLDPWD" && cygcheck ./haxelib.exe')
     & "$($env:CYG_ROOT)/bin/bash.exe" @('-lc', 'cd "$OLDPWD" && ls ./out')
     & "$($env:CYG_ROOT)/bin/bash.exe" @('-lc', 'cd "$OLDPWD" && ls ./out')
 
 
+- name: Check artifact
+  shell: bash
+  run: |
+    ls out
+    # Output should contain binaries zip, installer zip and nupkg
+    [ $(ls -1 out | wc -l) -eq "3" ]
+
 - name: Upload artifact
 - name: Upload artifact
-  uses: actions/[email protected]
+  uses: actions/upload-artifact@v3
   with:
   with:
     name: win${{env.ARCH}}Binaries
     name: win${{env.ARCH}}Binaries
     path: out
     path: out

+ 0 - 6
extra/github-actions/cache-opam.yml

@@ -1,6 +0,0 @@
-- name: Cache opam
-  id: cache-opam
-  uses: actions/[email protected]
-  with:
-    path: ~/.opam/
-    key: ${{ runner.os }}-${{ hashFiles('./opam', './libs/') }}-1

+ 4 - 2
extra/github-actions/install-nsis.yml

@@ -1,12 +1,14 @@
 - name: choco install nsis
 - name: choco install nsis
-  uses: nick-invision/retry@v1
+  uses: nick-invision/retry@v2
   with:
   with:
     timeout_minutes: 10
     timeout_minutes: 10
     max_attempts: 10
     max_attempts: 10
-    command: choco install --no-progress nsis.portable --version 3.02 -y
+    command: choco install --no-progress nsis.portable --version 3.09 -y
+
 - name: choco install things
 - name: choco install things
   shell: pwsh
   shell: pwsh
   run: choco install --no-progress curl wget 7zip.portable -y
   run: choco install --no-progress curl wget 7zip.portable -y
+
 - name: Prepend Chocolatey path
 - name: Prepend Chocolatey path
   shell: pwsh
   shell: pwsh
   run: Write-Host "::add-path::C:\ProgramData\chocolatey\bin"
   run: Write-Host "::add-path::C:\ProgramData\chocolatey\bin"

+ 2 - 7
extra/github-actions/install-ocaml-libs-windows.yml

@@ -1,11 +1,6 @@
 - name: Install OCaml libraries
 - name: Install OCaml libraries
-  if: steps.cache-opam.outputs.cache-hit != 'true'
   shell: pwsh
   shell: pwsh
   run: |
   run: |
     Set-PSDebug -Trace 1
     Set-PSDebug -Trace 1
-    & "$($env:CYG_ROOT)/bin/bash.exe" @('-lc', 'opam init mingw "https://github.com/fdopen/opam-repository-mingw.git#opam2" --comp 4.07.0+mingw${ARCH}c --switch 4.07.0+mingw${ARCH}c --auto-setup --yes 2>&1')
-    & "$($env:CYG_ROOT)/bin/bash.exe" @('-lc', 'opam update --yes 2>&1')
-    & "$($env:CYG_ROOT)/bin/bash.exe" @('-lc', 'cd "$OLDPWD" && opam pin add haxe . --kind=path --no-action --yes 2>&1')
-    & "$($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')
+    opam install haxe --deps-only
+    opam list

+ 30 - 8
extra/github-actions/install-ocaml-windows.yml

@@ -1,17 +1,39 @@
-- name: Install OCaml
+- name: Setup ocaml
+  id: ocaml
+  continue-on-error: true
+  uses: kLabz/setup-ocaml@win32
+  with:
+    ocaml-compiler: 4.08.1
+    opam-depext: false
+    opam-repositories: |
+      opam-repository-mingw: https://github.com/ocaml-opam/opam-repository-mingw.git#sunset
+      default: https://github.com/ocaml/opam-repository.git
+    opam-local-packages: |
+      haxe.opam
+    cache-prefix: w32-v1
+
+# TODO make it work on first try
+# (when cygwin cache doesn't exist, ocaml install fails with a curl error)
+- name: Setup ocaml (second chance)
+  if: steps.ocaml.outcome == 'failure'
+  uses: kLabz/setup-ocaml@win32
+  with:
+    ocaml-compiler: 4.08.1
+    opam-depext: false
+    opam-repositories: |
+      opam-repository-mingw: https://github.com/ocaml-opam/opam-repository-mingw.git#sunset
+      default: https://github.com/ocaml/opam-repository.git
+    opam-local-packages: |
+      haxe.opam
+    cache-prefix: w32-v1
+
+- name: Install dependencies
   shell: pwsh
   shell: pwsh
   run: |
   run: |
     Set-PSDebug -Trace 1
     Set-PSDebug -Trace 1
-    curl.exe -fsSL -o cygwin-setup.exe --retry 3 $($env:CYGWIN_SETUP)
-    Start-Process -FilePath "cygwin-setup.exe" -ArgumentList "-B -q -R $($env:CYG_ROOT) -l C:/tmp -s $($env:CYG_MIRROR) -P default -P make -P git -P zlib-devel -P rsync -P patch -P diffutils -P curl -P unzip -P tar -P m4 -P perl -P libpcre2-devel -P mbedtls-devel -P mingw64-$($env:MINGW_ARCH)-zlib -P mingw64-$($env:MINGW_ARCH)-gcc-core -P mingw64-$($env:MINGW_ARCH)-pcre2 --allow-unsupported-windows" -Wait -RedirectStandardOutput cygwin-setup-out.txt
-    Get-Content cygwin-setup-out.txt
-    & "$($env:CYG_ROOT)/bin/bash.exe" @('--norc', '--noprofile', '/etc/postinstall/ca-certificates.sh')
-    curl.exe -fsSL -o "opam.tar.xz" --retry 3 https://github.com/fdopen/opam-repository-mingw/releases/download/0.0.0.2/opam$($env:ARCH).tar.xz
     curl.exe -fsSL -o "libmbedtls.tar.xz" --retry 3 https://github.com/Simn/mingw64-mbedtls/releases/download/2.16.3/mingw64-$($env:MINGW_ARCH)-mbedtls-2.16.3-1.tar.xz
     curl.exe -fsSL -o "libmbedtls.tar.xz" --retry 3 https://github.com/Simn/mingw64-mbedtls/releases/download/2.16.3/mingw64-$($env:MINGW_ARCH)-mbedtls-2.16.3-1.tar.xz
     & "$($env:CYG_ROOT)/bin/bash.exe" @('-lc', 'curl -L https://cpanmin.us | perl - App::cpanminus')
     & "$($env:CYG_ROOT)/bin/bash.exe" @('-lc', 'curl -L https://cpanmin.us | perl - App::cpanminus')
     & "$($env:CYG_ROOT)/bin/bash.exe" @('-lc', 'cpanm IPC::System::Simple module')
     & "$($env:CYG_ROOT)/bin/bash.exe" @('-lc', 'cpanm IPC::System::Simple module')
     & "$($env:CYG_ROOT)/bin/bash.exe" @('-lc', 'cpanm String::ShellQuote')
     & "$($env:CYG_ROOT)/bin/bash.exe" @('-lc', 'cpanm String::ShellQuote')
     & "$($env:CYG_ROOT)/bin/bash.exe" @('-lc', 'echo "$OLDPWD"')
     & "$($env:CYG_ROOT)/bin/bash.exe" @('-lc', 'echo "$OLDPWD"')
     & "$($env:CYG_ROOT)/bin/bash.exe" @('-lc', 'cd "$OLDPWD" && tar -C / -xvf libmbedtls.tar.xz')
     & "$($env:CYG_ROOT)/bin/bash.exe" @('-lc', 'cd "$OLDPWD" && tar -C / -xvf libmbedtls.tar.xz')
-    & "$($env:CYG_ROOT)/bin/bash.exe" @('-lc', 'cd "$OLDPWD" && tar -xf opam.tar.xz')
-    & "$($env:CYG_ROOT)/bin/bash.exe" @('-lc', 'cd "$OLDPWD" && bash opam${ARCH}/install.sh')

+ 11 - 7
extra/github-actions/install-ocaml-windows64.yml

@@ -1,16 +1,20 @@
-- name: Install OCaml
+- name: Setup ocaml
+  uses: ocaml/setup-ocaml@v2
+  with:
+    ocaml-compiler: 4.08.1
+    opam-repositories: |
+      opam-repository-mingw: https://github.com/ocaml-opam/opam-repository-mingw.git#sunset
+      default: https://github.com/ocaml/opam-repository.git
+    opam-local-packages: |
+      haxe.opam
+
+- name: Install dependencies
   shell: pwsh
   shell: pwsh
   run: |
   run: |
     Set-PSDebug -Trace 1
     Set-PSDebug -Trace 1
-    curl.exe -fsSL -o cygwin-setup.exe --retry 3 $($env:CYGWIN_SETUP)
-    Start-Process -FilePath "cygwin-setup.exe" -ArgumentList "-B -q -R $($env:CYG_ROOT) -l C:/tmp -s $($env:CYG_MIRROR) -P default -P make -P git -P zlib-devel -P rsync -P patch -P diffutils -P curl -P unzip -P tar -P m4 -P perl -P libpcre2-devel -P mbedtls-devel -P mingw64-$($env:MINGW_ARCH)-zlib -P mingw64-$($env:MINGW_ARCH)-gcc-core -P mingw64-$($env:MINGW_ARCH)-pcre2" -Wait -RedirectStandardOutput cygwin-setup-out.txt
-    Get-Content cygwin-setup-out.txt
-    curl.exe -fsSL -o "opam.tar.xz" --retry 3 https://github.com/fdopen/opam-repository-mingw/releases/download/0.0.0.2/opam$($env:ARCH).tar.xz
     curl.exe -fsSL -o "libmbedtls.tar.xz" --retry 3 https://github.com/Simn/mingw64-mbedtls/releases/download/2.16.3/mingw64-$($env:MINGW_ARCH)-mbedtls-2.16.3-1.tar.xz
     curl.exe -fsSL -o "libmbedtls.tar.xz" --retry 3 https://github.com/Simn/mingw64-mbedtls/releases/download/2.16.3/mingw64-$($env:MINGW_ARCH)-mbedtls-2.16.3-1.tar.xz
     & "$($env:CYG_ROOT)/bin/bash.exe" @('-lc', 'curl -L https://cpanmin.us | perl - App::cpanminus')
     & "$($env:CYG_ROOT)/bin/bash.exe" @('-lc', 'curl -L https://cpanmin.us | perl - App::cpanminus')
     & "$($env:CYG_ROOT)/bin/bash.exe" @('-lc', 'cpanm IPC::System::Simple module')
     & "$($env:CYG_ROOT)/bin/bash.exe" @('-lc', 'cpanm IPC::System::Simple module')
     & "$($env:CYG_ROOT)/bin/bash.exe" @('-lc', 'cpanm String::ShellQuote')
     & "$($env:CYG_ROOT)/bin/bash.exe" @('-lc', 'cpanm String::ShellQuote')
     & "$($env:CYG_ROOT)/bin/bash.exe" @('-lc', 'echo "$OLDPWD"')
     & "$($env:CYG_ROOT)/bin/bash.exe" @('-lc', 'echo "$OLDPWD"')
     & "$($env:CYG_ROOT)/bin/bash.exe" @('-lc', 'cd "$OLDPWD" && tar -C / -xvf libmbedtls.tar.xz')
     & "$($env:CYG_ROOT)/bin/bash.exe" @('-lc', 'cd "$OLDPWD" && tar -C / -xvf libmbedtls.tar.xz')
-    & "$($env:CYG_ROOT)/bin/bash.exe" @('-lc', 'cd "$OLDPWD" && tar -xf opam.tar.xz')
-    & "$($env:CYG_ROOT)/bin/bash.exe" @('-lc', 'cd "$OLDPWD" && bash opam${ARCH}/install.sh')

+ 4 - 0
extra/github-actions/test-windows.yml

@@ -1,3 +1,7 @@
+- uses: actions/setup-node@v3
+  with:
+    node-version: 18.17.1
+
 # - name: Quick test
 # - name: Quick test
 #   shell: pwsh
 #   shell: pwsh
 #   run: |
 #   run: |

+ 56 - 53
extra/github-actions/workflows/main.yml

@@ -9,13 +9,9 @@ jobs:
     env:
     env:
       ACTIONS_ALLOW_UNSECURE_COMMANDS: true
       ACTIONS_ALLOW_UNSECURE_COMMANDS: true
       PLATFORM: windows64
       PLATFORM: windows64
-      OPAMYES: 1
-      OPAMROOT: D:\.opam
-      CYG_MIRROR: http://mirrors.kernel.org/sourceware/cygwin/
       ARCH: 64
       ARCH: 64
       MINGW_ARCH: x86_64
       MINGW_ARCH: x86_64
-      CYGWIN_SETUP: https://cygwin.com/setup-x86_64.exe
-      CYG_ROOT: C:/cygwin64
+      CYG_ROOT: D:\cygwin
     steps:
     steps:
       - uses: actions/checkout@main
       - uses: actions/checkout@main
         with:
         with:
@@ -26,15 +22,8 @@ jobs:
           echo "C:\msys64\usr\bin" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append
           echo "C:\msys64\usr\bin" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append
           rm C:\msys64\usr\bin\bash.exe
           rm C:\msys64\usr\bin\bash.exe
 
 
-      - name: Cache opam
-        id: cache-opam
-        uses: actions/[email protected]
-        with:
-          path: D:\.opam
-          key: ${{ runner.os }}64-${{ hashFiles('./opam', './libs/') }}
-
-      @import install-neko-windows.yml
       @import install-nsis.yml
       @import install-nsis.yml
+      @import install-neko-windows.yml
       @import install-ocaml-windows64.yml
       @import install-ocaml-windows64.yml
       @import install-ocaml-libs-windows.yml
       @import install-ocaml-libs-windows.yml
       @import build-windows.yml
       @import build-windows.yml
@@ -44,13 +33,9 @@ jobs:
     env:
     env:
       ACTIONS_ALLOW_UNSECURE_COMMANDS: true
       ACTIONS_ALLOW_UNSECURE_COMMANDS: true
       PLATFORM: windows
       PLATFORM: windows
-      OPAMYES: 1
-      OPAMROOT: D:\.opam
-      CYG_MIRROR: http://mirrors.kernel.org/sourceware/cygwin-archive/20221123
       ARCH: 32
       ARCH: 32
       MINGW_ARCH: i686
       MINGW_ARCH: i686
-      CYGWIN_SETUP: https://cygwin.com/setup-x86.exe
-      CYG_ROOT: C:/cygwin
+      CYG_ROOT: D:\cygwin
     steps:
     steps:
       - uses: actions/checkout@main
       - uses: actions/checkout@main
         with:
         with:
@@ -61,30 +46,33 @@ jobs:
           echo "C:\msys64\usr\bin" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append
           echo "C:\msys64\usr\bin" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append
           rm C:\msys64\usr\bin\bash.exe
           rm C:\msys64\usr\bin\bash.exe
 
 
-      - name: Cache opam
-        id: cache-opam
-        uses: actions/[email protected]
-        with:
-          path: D:\.opam
-          key: ${{ runner.os }}32-${{ hashFiles('./opam', './libs/') }}
-
-      @import install-neko-windows.yml
       @import install-nsis.yml
       @import install-nsis.yml
+      @import install-neko-windows.yml
       @import install-ocaml-windows.yml
       @import install-ocaml-windows.yml
       @import install-ocaml-libs-windows.yml
       @import install-ocaml-libs-windows.yml
       @import build-windows.yml
       @import build-windows.yml
 
 
   linux-build:
   linux-build:
-    runs-on: ubuntu-18.04
+    runs-on: ubuntu-20.04
     env:
     env:
       PLATFORM: linux64
       PLATFORM: linux64
       OPAMYES: 1
       OPAMYES: 1
+    strategy:
+      fail-fast: false
+      matrix:
+        ocaml: ["4.08.1", "5.0.0"]
     steps:
     steps:
       - uses: actions/checkout@main
       - uses: actions/checkout@main
         with:
         with:
           submodules: recursive
           submodules: recursive
 
 
-      @import cache-opam.yml
+      - name: Cache opam
+        id: cache-opam
+        uses: actions/[email protected]
+        with:
+          path: ~/.opam/
+          key: ${{ runner.os }}-${{ matrix.ocaml }}-${{ hashFiles('./haxe.opam', './libs/') }}
+
       @import install-neko-unix.yml
       @import install-neko-unix.yml
 
 
       - name: Install dependencies
       - name: Install dependencies
@@ -101,6 +89,7 @@ jobs:
           set -ex
           set -ex
           opam init # --disable-sandboxing
           opam init # --disable-sandboxing
           opam update
           opam update
+          opam switch create ${{ matrix.ocaml }}
           opam pin add haxe . --no-action
           opam pin add haxe . --no-action
           opam install haxe --deps-only --assume-depexts
           opam install haxe --deps-only --assume-depexts
           opam list
           opam list
@@ -125,9 +114,10 @@ jobs:
       - name: Extract branch name
       - name: Extract branch name
         id: extract_branch
         id: extract_branch
         shell: bash
         shell: bash
-        run: echo "##[set-output name=branch;]$(echo ${GITHUB_REF#refs/heads/})"
+        run: echo "branch=${GITHUB_REF#refs/heads/}" >> $GITHUB_OUTPUT
 
 
       - name: Build xmldoc
       - name: Build xmldoc
+        if: matrix.ocaml == '4.08.1'
         run: |
         run: |
           set -ex
           set -ex
           make -s xmldoc
           make -s xmldoc
@@ -139,20 +129,21 @@ jobs:
           EOL
           EOL
 
 
       - name: Upload artifact
       - name: Upload artifact
-        uses: actions/upload-artifact@v1.0.0
+        uses: actions/upload-artifact@v3
         with:
         with:
-          name: linuxBinaries
+          name: linuxBinaries${{ (matrix.ocaml == '5.0.0' && '_ocaml5') || '' }}
           path: out
           path: out
 
 
       - name: Upload xmldoc artifact
       - name: Upload xmldoc artifact
-        uses: actions/[email protected]
+        uses: actions/upload-artifact@v3
+        if: matrix.ocaml == '4.08.1'
         with:
         with:
           name: xmldoc
           name: xmldoc
           path: extra/doc
           path: extra/doc
 
 
   linux-test:
   linux-test:
     needs: linux-build
     needs: linux-build
-    runs-on: ubuntu-18.04
+    runs-on: ubuntu-20.04
     env:
     env:
       PLATFORM: linux64
       PLATFORM: linux64
       TEST: ${{matrix.target}}
       TEST: ${{matrix.target}}
@@ -161,6 +152,7 @@ jobs:
     strategy:
     strategy:
       fail-fast: false
       fail-fast: false
       matrix:
       matrix:
+        ocaml: ["4.08.1", "5.0.0"]
         target: [macro, js, hl, cpp, 'java,jvm', cs, php, python, lua, flash, neko]
         target: [macro, js, hl, cpp, 'java,jvm', cs, php, python, lua, flash, neko]
         include:
         include:
           - target: hl
           - target: hl
@@ -170,14 +162,15 @@ jobs:
           - target: lua
           - target: lua
             APT_PACKAGES: ncurses-dev
             APT_PACKAGES: ncurses-dev
           - target: flash
           - target: flash
-            APT_PACKAGES: libglib2.0-0 libfreetype6 xvfb
+            APT_PACKAGES: libglib2.0-0 libgtk2.0-0 libfreetype6 xvfb
     steps:
     steps:
       - uses: actions/checkout@main
       - uses: actions/checkout@main
         with:
         with:
           submodules: recursive
           submodules: recursive
-      - uses: actions/download-artifact@v1
+      - uses: actions/download-artifact@v3
         with:
         with:
-          name: linuxBinaries
+          name: linuxBinaries${{ (matrix.ocaml == '5.0.0' && '_ocaml5') || '' }}
+          path: linuxBinaries
 
 
       @import install-neko-unix.yml
       @import install-neko-unix.yml
 
 
@@ -219,7 +212,7 @@ jobs:
 
 
   test-docgen:
   test-docgen:
     needs: linux-build
     needs: linux-build
-    runs-on: ubuntu-18.04
+    runs-on: ubuntu-20.04
     env:
     env:
       PLATFORM: linux64
       PLATFORM: linux64
       HXCPP_COMPILE_CACHE: ~/hxcache
       HXCPP_COMPILE_CACHE: ~/hxcache
@@ -228,12 +221,13 @@ jobs:
         with:
         with:
           submodules: recursive
           submodules: recursive
 
 
-      - uses: actions/download-artifact@v1
+      - uses: actions/download-artifact@v3
         with:
         with:
           name: linuxBinaries
           name: linuxBinaries
+          path: linuxBinaries
 
 
       - name: Download xmldoc artifact
       - name: Download xmldoc artifact
-        uses: actions/download-artifact@v2
+        uses: actions/download-artifact@v3
         with:
         with:
           name: xmldoc
           name: xmldoc
           path: xmldoc
           path: xmldoc
@@ -279,14 +273,14 @@ jobs:
         working-directory: ${{github.workspace}}/tests/docgen
         working-directory: ${{github.workspace}}/tests/docgen
 
 
   linux-arm64:
   linux-arm64:
-    runs-on: ubuntu-18.04
+    runs-on: ubuntu-20.04
     permissions:
     permissions:
       packages: write
       packages: write
     env:
     env:
       FORCE_COLOR: 1
       FORCE_COLOR: 1
     steps:
     steps:
       - name: Login to GitHub Container Registry
       - name: Login to GitHub Container Registry
-        uses: docker/login-action@v1
+        uses: docker/login-action@v2
         with:
         with:
           registry: ghcr.io
           registry: ghcr.io
           username: ${{ github.actor }}
           username: ${{ github.actor }}
@@ -297,7 +291,7 @@ jobs:
 
 
       - name: Set up QEMU
       - name: Set up QEMU
         id: qemu
         id: qemu
-        uses: docker/setup-qemu-action@v1
+        uses: docker/setup-qemu-action@v2
         with:
         with:
             image: tonistiigi/binfmt:latest
             image: tonistiigi/binfmt:latest
             platforms: all
             platforms: all
@@ -329,7 +323,7 @@ jobs:
           EARTHLY_REMOTE_CACHE: "ghcr.io/${{env.CONTAINER_REG}}_cache:build-${{env.CONTAINER_TAG}}-arm64"
           EARTHLY_REMOTE_CACHE: "ghcr.io/${{env.CONTAINER_REG}}_cache:build-${{env.CONTAINER_TAG}}-arm64"
 
 
       - name: Upload artifact
       - name: Upload artifact
-        uses: actions/upload-artifact@v1.0.0
+        uses: actions/upload-artifact@v3
         with:
         with:
           name: linuxArm64Binaries
           name: linuxArm64Binaries
           path: out/linux/arm64
           path: out/linux/arm64
@@ -345,7 +339,13 @@ jobs:
         with:
         with:
           submodules: recursive
           submodules: recursive
 
 
-      @import cache-opam.yml
+      - name: Cache opam
+        id: cache-opam
+        uses: actions/[email protected]
+        with:
+          path: ~/.opam/
+          key: ${{ runner.os }}-${{ hashFiles('./haxe.opam', './libs/') }}
+
       @import install-neko-unix.yml
       @import install-neko-unix.yml
       @import build-mac.yml
       @import build-mac.yml
 
 
@@ -367,9 +367,10 @@ jobs:
       - uses: actions/checkout@main
       - uses: actions/checkout@main
         with:
         with:
           submodules: recursive
           submodules: recursive
-      - uses: actions/download-artifact@v1
+      - uses: actions/download-artifact@v3
         with:
         with:
           name: win${{env.ARCH}}Binaries
           name: win${{env.ARCH}}Binaries
+          path: win${{env.ARCH}}Binaries
 
 
       @import install-neko-windows.yml
       @import install-neko-windows.yml
       @import test-windows.yml
       @import test-windows.yml
@@ -393,9 +394,10 @@ jobs:
       - uses: actions/checkout@main
       - uses: actions/checkout@main
         with:
         with:
           submodules: recursive
           submodules: recursive
-      - uses: actions/download-artifact@v1
+      - uses: actions/download-artifact@v3
         with:
         with:
           name: win${{env.ARCH}}Binaries
           name: win${{env.ARCH}}Binaries
+          path: win${{env.ARCH}}Binaries
 
 
       @import install-neko-windows.yml
       @import install-neko-windows.yml
       @import test-windows.yml
       @import test-windows.yml
@@ -419,9 +421,10 @@ jobs:
       - uses: actions/checkout@main
       - uses: actions/checkout@main
         with:
         with:
           submodules: recursive
           submodules: recursive
-      - uses: actions/download-artifact@v1
+      - uses: actions/download-artifact@v3
         with:
         with:
           name: macBinaries
           name: macBinaries
+          path: macBinaries
 
 
       @import install-neko-unix.yml
       @import install-neko-unix.yml
       @import test-mac.yml
       @import test-mac.yml
@@ -429,7 +432,7 @@ jobs:
   deploy:
   deploy:
     if: success() && github.repository_owner == 'HaxeFoundation' && github.event_name != 'pull_request'
     if: success() && github.repository_owner == 'HaxeFoundation' && github.event_name != 'pull_request'
     needs: [linux-test, linux-arm64, mac-test, windows-test, windows64-test]
     needs: [linux-test, linux-arm64, mac-test, windows-test, windows64-test]
-    runs-on: ubuntu-18.04
+    runs-on: ubuntu-20.04
     steps:
     steps:
       # this is only needed for to get `COMMIT_DATE`...
       # this is only needed for to get `COMMIT_DATE`...
       # maybe https://github.community/t/expose-commit-timestamp-in-the-github-context-data/16460/3
       # maybe https://github.community/t/expose-commit-timestamp-in-the-github-context-data/16460/3
@@ -438,7 +441,7 @@ jobs:
         uses: actions/checkout@main
         uses: actions/checkout@main
 
 
       - name: Download build artifacts
       - name: Download build artifacts
-        uses: actions/download-artifact@v2
+        uses: actions/download-artifact@v3
 
 
       - name: Install awscli
       - name: Install awscli
         run: |
         run: |
@@ -450,7 +453,7 @@ jobs:
       - name: Extract branch name
       - name: Extract branch name
         id: extract_branch
         id: extract_branch
         shell: bash
         shell: bash
-        run: echo "##[set-output name=branch;]$(echo ${GITHUB_REF#refs/heads/})"
+        run: echo "branch=${GITHUB_REF#refs/heads/}" >> $GITHUB_OUTPUT
 
 
       - name: Upload binaries
       - name: Upload binaries
         shell: bash
         shell: bash
@@ -505,7 +508,7 @@ jobs:
   deploy_apidoc:
   deploy_apidoc:
     if: success() && github.repository_owner == 'HaxeFoundation' && github.event_name != 'pull_request'
     if: success() && github.repository_owner == 'HaxeFoundation' && github.event_name != 'pull_request'
     needs: [linux-test, linux-arm64, mac-test, windows-test, windows64-test]
     needs: [linux-test, linux-arm64, mac-test, windows-test, windows64-test]
-    runs-on: ubuntu-18.04
+    runs-on: ubuntu-20.04
     steps:
     steps:
       - name: Install dependencies
       - name: Install dependencies
         run: |
         run: |
@@ -513,7 +516,7 @@ jobs:
           sudo apt-get install -qqy libc6
           sudo apt-get install -qqy libc6
 
 
       - name: Download Haxe
       - name: Download Haxe
-        uses: actions/download-artifact@v2
+        uses: actions/download-artifact@v3
         with:
         with:
           name: linuxBinaries
           name: linuxBinaries
           path: linuxBinaries
           path: linuxBinaries
@@ -529,7 +532,7 @@ jobs:
           sudo ln -s `pwd`/linuxBinaries/std /usr/local/share/haxe/std
           sudo ln -s `pwd`/linuxBinaries/std /usr/local/share/haxe/std
 
 
       - name: Download xmldoc artifact
       - name: Download xmldoc artifact
-        uses: actions/download-artifact@v2
+        uses: actions/download-artifact@v3
         with:
         with:
           name: xmldoc
           name: xmldoc
           path: xmldoc
           path: xmldoc

+ 1 - 1
extra/haxelib_src

@@ -1 +1 @@
-Subproject commit 4e4b03464ae272179692edf92c2f84848901e07d
+Subproject commit 70ff6b69a5b35049d767056555c0bf7a54e8ad4e

+ 1 - 1
extra/installer.nsi

@@ -21,7 +21,7 @@
 !define VERLONG "%%VERLONG%%"
 !define VERLONG "%%VERLONG%%"
 
 
 ; Define Neko info
 ; Define Neko info
-!define NEKO_VERSION "2.3.0"
+!define NEKO_VERSION "%%NEKO_VERSION%%"
 
 
 ; Installer details
 ; Installer details
 VIAddVersionKey "CompanyName" "Haxe Foundation"
 VIAddVersionKey "CompanyName" "Haxe Foundation"

+ 2 - 2
extra/mac-installer/scripts/neko-postinstall.sh

@@ -15,5 +15,5 @@ ln -s /usr/local/lib/neko/nekoc /usr/local/bin/nekoc
 ln -s /usr/local/lib/neko/nekoml /usr/local/bin/nekoml
 ln -s /usr/local/lib/neko/nekoml /usr/local/bin/nekoml
 ln -s /usr/local/lib/neko/nekotools /usr/local/bin/nekotools
 ln -s /usr/local/lib/neko/nekotools /usr/local/bin/nekotools
 ln -s /usr/local/lib/neko/libneko.dylib /usr/local/lib/libneko.dylib
 ln -s /usr/local/lib/neko/libneko.dylib /usr/local/lib/libneko.dylib
-ln -s /usr/local/lib/neko/libneko.2.dylib /usr/local/lib/libneko.2.dylib
-ln -s /usr/local/lib/neko/libneko.2.1.0.dylib /usr/local/lib/libneko.2.1.0.dylib
+ln -s /usr/local/lib/neko/libneko.%%NEKO_MAJOR_VERSION%%.dylib /usr/local/lib/libneko.%%NEKO_MAJOR_VERSION%%.dylib
+ln -s /usr/local/lib/neko/libneko.%%NEKO_VERSION%%.dylib /usr/local/lib/libneko.%%NEKO_VERSION%%.dylib

+ 15 - 11
extra/release-checklist.txt

@@ -3,28 +3,32 @@
 - Check that haxelib is working
 - Check that haxelib is working
 - Make sure to update the haxelib submodule
 - Make sure to update the haxelib submodule
 - Check that the run-time haxelibs are ready for release: hxcpp, hxjava, hxcs
 - Check that the run-time haxelibs are ready for release: hxcpp, hxjava, hxcs
-- Check that the osx & windows installers has the latest neko release in "Makefile" and "Makefile.win" files
+- Check that the NEKO_VERSION variable in the "Makefile" is set to the latest Neko version
 
 
 # Making the release
 # Making the release
 
 
 - Make sure CHANGES.txt has a proper date set!
 - Make sure CHANGES.txt has a proper date set!
 - Make sure `version` in globals.ml has the correct value
 - Make sure `version` in globals.ml has the correct value
-- Update `version` in `./opam`
+- Make sure the copyright year in args.ml has the correct value
+- Update `version` in `haxe.opam`
 - Check if the protocolVersion in displayJson.ml has to be updated
 - Check if the protocolVersion in displayJson.ml has to be updated
-- Make an empty GitHub release in https://github.com/HaxeFoundation/haxe/releases (do this first because we need the tag for the builds)
-- Wait for the CI to build (check https://build.haxe.org/builds/haxe/)
-- Get https://github.com/simn/hxgithub
-- Store your GitHub personal access token in .github-token
-- Run something like this: `neko release.n -h 4.0.0-rc.1 -u -uw -ur -d haxe_2019-02-01_development_1fdd3d5.zip --dry`
-- Tell yourself that you're gonna fix `-doc` generation next time
-- Write the announcement to `./haxe-version/RELEASE.md`
-- If everything was working, run the command again without `--dry` (and probably without the `-d`)
+- Create a version tag and push it with above changes (CI needs to run on the tag)
+- Make an empty GitHub release in https://github.com/HaxeFoundation/haxe/releases
+- Wait for the CI to build (check https://build.haxe.org/builds/haxe/, look for `haxe_[date]_refs/tags`)
+- Get https://github.com/HaxeFoundation/hxgithub
+- Follow "Haxe releases" section of hxgithub README, with the equivalent of `-d haxe_2023-04-28_refs/tags/4.3.1_964c84c.tar.gz`
+	- Tell yourself that you're gonna fix `-doc` generation next time
+	- Make sure changelog isn't empty in `./haxe-version/CHANGES.md`
+	- Write the announcement to `./haxe-version/RELEASE.md`
+	- If everything was working, run the command again without `--dry`
 - Update https://github.com/HaxeFoundation/haxe.org/blob/staging/downloads/versions.json
 - Update https://github.com/HaxeFoundation/haxe.org/blob/staging/downloads/versions.json
+- Wait for staging to update, check everything related to release and merge to master
 
 
 # Cleanup
 # Cleanup
 
 
 - Remove issues with released fixes from the "Hotfix" milestone: https://github.com/HaxeFoundation/haxe/milestone/18
 - Remove issues with released fixes from the "Hotfix" milestone: https://github.com/HaxeFoundation/haxe/milestone/18
+- Set back the version in `globals.ml` to something appropriate for nightlies
 
 
 # Announcing the release
 # Announcing the release
 
 
-- Find someone to announce the release on our various communication channels
+- Find someone to announce the release on our various communication channels

+ 7 - 5
opam → haxe.opam

@@ -1,6 +1,6 @@
 opam-version: "2.0"
 opam-version: "2.0"
 name: "haxe"
 name: "haxe"
-version: "4.2.4"
+version: "4.3.0"
 synopsis: "Multi-target universal programming language"
 synopsis: "Multi-target universal programming language"
 description: """
 description: """
 Haxe is an open source toolkit based on a modern,
 Haxe is an open source toolkit based on a modern,
@@ -19,17 +19,19 @@ build: [
 install: [make "install" "INSTALL_DIR=%{prefix}%"]
 install: [make "install" "INSTALL_DIR=%{prefix}%"]
 remove: [make "uninstall" "INSTALL_DIR=%{prefix}%"]
 remove: [make "uninstall" "INSTALL_DIR=%{prefix}%"]
 depends: [
 depends: [
-  "ocaml" {>= "4.02"}
+  ("ocaml" {>= "5.0"} & ("camlp5" {build}))
+    | ("ocaml" {>= "4.08" & < "5.0"} & ("camlp5" {build & = "8.00"}))
   "ocamlfind" {build}
   "ocamlfind" {build}
   "dune" {>= "1.11"}
   "dune" {>= "1.11"}
-  "camlp5" {build & = "8.00"}
   "sedlex" {>= "2.0"}
   "sedlex" {>= "2.0"}
   "xml-light"
   "xml-light"
   "extlib" {>= "1.7.8"}
   "extlib" {>= "1.7.8"}
-  "ptmap" {>= "2.0.0"}
   "sha"
   "sha"
+  "camlp-streams"
   "conf-libpcre2-8"
   "conf-libpcre2-8"
   "conf-zlib"
   "conf-zlib"
   "conf-neko"
   "conf-neko"
-  "luv"
+  "luv" {>= "0.5.12"}
+  "ipaddr"
+  "terminal_size"
 ]
 ]

+ 3 - 3
libs/extc/extc.ml

@@ -110,10 +110,10 @@ let input_zip ?(bufsize=65536) ch =
 	let buf = ref "" in
 	let buf = ref "" in
 	let p = ref 0 in
 	let p = ref 0 in
 	let z = zlib_inflate_init() in
 	let z = zlib_inflate_init() in
-	let rec fill_buffer() =
+	let fill_buffer() =
 		let rec loop pos len =
 		let rec loop pos len =
 			if len > 0 || pos = 0 then begin
 			if len > 0 || pos = 0 then begin
-				let r = zlib_inflate z (Bytes.unsafe_to_string tmp_in) pos len tmp_out 0 bufsize (if pos = 0 && len = 0 then Z_FINISH else Z_SYNC_FLUSH) in
+				let r = zlib_inflate z ~src:(Bytes.unsafe_to_string tmp_in) ~spos:pos ~slen:len ~dst:tmp_out ~dpos:0 ~dlen:bufsize (if pos = 0 && len = 0 then Z_FINISH else Z_SYNC_FLUSH) in
 				Buffer.add_subbytes tmp_buf tmp_out 0 r.z_wrote;
 				Buffer.add_subbytes tmp_buf tmp_out 0 r.z_wrote;
 				loop (pos + r.z_read) (len - r.z_read);
 				loop (pos + r.z_read) (len - r.z_read);
 			end
 			end
@@ -155,7 +155,7 @@ let output_zip ?(bufsize=65536) ?(level=9) ch =
 	let tmp_out = Bytes.create bufsize in
 	let tmp_out = Bytes.create bufsize in
 	let p = ref 0 in
 	let p = ref 0 in
 	let rec flush finish =
 	let rec flush finish =
-		let r = zlib_deflate z (Bytes.unsafe_to_string out) 0 !p tmp_out 0 bufsize (if finish then Z_FINISH else Z_SYNC_FLUSH) in
+		let r = zlib_deflate z ~src:(Bytes.unsafe_to_string out) ~spos:0 ~slen:!p ~dst:tmp_out ~dpos:0 ~dlen:bufsize (if finish then Z_FINISH else Z_SYNC_FLUSH) in
 		ignore(IO.really_output ch tmp_out 0 r.z_wrote);
 		ignore(IO.really_output ch tmp_out 0 r.z_wrote);
 		let remain = !p - r.z_read in
 		let remain = !p - r.z_read in
 		Bytes.blit out r.z_read out 0 remain;
 		Bytes.blit out r.z_read out 0 remain;

+ 21 - 21
libs/extc/extc_stubs.c

@@ -92,7 +92,7 @@ int Zflush_val(value zflush_val) {
 		case 4: return Z_FINISH;
 		case 4: return Z_FINISH;
 		// TODO: support Z_BLOCK and Z_TREE
 		// TODO: support Z_BLOCK and Z_TREE
 		// TODO: append the received value
 		// TODO: append the received value
-		default: failwith("Error in `Zflush_val` (extc_stubs.c): Unknown zflush value");
+		default: caml_failwith("Error in `Zflush_val` (extc_stubs.c): Unknown zflush value");
 	}
 	}
 	assert(0);
 	assert(0);
 }
 }
@@ -222,14 +222,14 @@ CAMLprim value zlib_deflate_init2(value level_val, value window_bits_val) {
 			break;
 			break;
 		case Z_STREAM_ERROR:
 		case Z_STREAM_ERROR:
 			// TODO: use stream->msg to get _zlib_'s text message
 			// TODO: use stream->msg to get _zlib_'s text message
-			failwith("Error in `zlib_deflate_init2` (extc_stubs.c): call to `deflateInit2` failed: Z_STREAM_ERROR");
+			caml_failwith("Error in `zlib_deflate_init2` (extc_stubs.c): call to `deflateInit2` failed: Z_STREAM_ERROR");
 			break;
 			break;
 		case Z_VERSION_ERROR:
 		case Z_VERSION_ERROR:
 			// TODO: use stream->msg to get _zlib_'s text message
 			// TODO: use stream->msg to get _zlib_'s text message
-			failwith("Error in `zlib_deflate_init2` (extc_stubs.c): call to `deflateInit2` failed: Z_VERSION_ERROR");
+			caml_failwith("Error in `zlib_deflate_init2` (extc_stubs.c): call to `deflateInit2` failed: Z_VERSION_ERROR");
 			break;
 			break;
 		default:
 		default:
-			failwith("Error in `zlib_deflate_init2` (extc_stubs.c): unknown return code from `deflateInit2`");
+			caml_failwith("Error in `zlib_deflate_init2` (extc_stubs.c): unknown return code from `deflateInit2`");
 	}
 	}
 	assert(0);
 	assert(0);
 }
 }
@@ -275,7 +275,7 @@ CAMLprim value zlib_deflate(value stream_val, value src, value spos, value slen,
 	if (deflate_result == Z_OK || deflate_result == Z_STREAM_END) {
 	if (deflate_result == Z_OK || deflate_result == Z_STREAM_END) {
 		stream->next_in = NULL;
 		stream->next_in = NULL;
 		stream->next_out = NULL;
 		stream->next_out = NULL;
-		value zresult = alloc_small(3, 0);
+		value zresult = caml_alloc_small(3, 0);
 		// z_finish
 		// z_finish
 		Field(zresult, 0) = Val_bool(deflate_result == Z_STREAM_END);
 		Field(zresult, 0) = Val_bool(deflate_result == Z_STREAM_END);
 		// z_read
 		// z_read
@@ -291,14 +291,14 @@ CAMLprim value zlib_deflate(value stream_val, value src, value spos, value slen,
 			break;
 			break;
 		case Z_STREAM_ERROR:
 		case Z_STREAM_ERROR:
 			// TODO: use stream->msg to get _zlib_'s text message
 			// TODO: use stream->msg to get _zlib_'s text message
-			failwith("Error in `zlib_deflate` (extc_stubs.c): call to `deflate` failed: Z_STREAM_ERROR");
+			caml_failwith("Error in `zlib_deflate` (extc_stubs.c): call to `deflate` failed: Z_STREAM_ERROR");
 			break;
 			break;
 		case Z_BUF_ERROR:
 		case Z_BUF_ERROR:
 			// TODO: use stream->msg to get _zlib_'s text message
 			// TODO: use stream->msg to get _zlib_'s text message
-			failwith("Error in `zlib_deflate` (extc_stubs.c): call to `deflate` failed: Z_BUF_ERROR");
+			caml_failwith("Error in `zlib_deflate` (extc_stubs.c): call to `deflate` failed: Z_BUF_ERROR");
 			break;
 			break;
 		default:
 		default:
-			failwith("Error in `zlib_deflate` (extc_stubs.c): unknown return code from `deflate`");
+			caml_failwith("Error in `zlib_deflate` (extc_stubs.c): unknown return code from `deflate`");
 	}
 	}
 	assert(0);
 	assert(0);
 }
 }
@@ -309,14 +309,14 @@ CAMLprim value zlib_deflate_bytecode(value *arg, int nargs) {
 
 
 CAMLprim value zlib_deflate_end(value zv) {
 CAMLprim value zlib_deflate_end(value zv) {
 	if( deflateEnd(ZStreamP_val(zv)) != 0 )
 	if( deflateEnd(ZStreamP_val(zv)) != 0 )
-		failwith("zlib_deflate_end");
+		caml_failwith("zlib_deflate_end");
 	return Val_unit;
 	return Val_unit;
 }
 }
 
 
 CAMLprim value zlib_inflate_init(value wbits) {
 CAMLprim value zlib_inflate_init(value wbits) {
 	value z = zlib_new_stream();
 	value z = zlib_new_stream();
 	if( inflateInit2(ZStreamP_val(z),Int_val(wbits)) != Z_OK )
 	if( inflateInit2(ZStreamP_val(z),Int_val(wbits)) != Z_OK )
-		failwith("zlib_inflate_init");
+		caml_failwith("zlib_inflate_init");
 	return z;
 	return z;
 }
 }
 
 
@@ -330,12 +330,12 @@ CAMLprim value zlib_inflate( value zv, value src, value spos, value slen, value
 	z->avail_in = Int_val(slen);
 	z->avail_in = Int_val(slen);
 	z->avail_out = Int_val(dlen);
 	z->avail_out = Int_val(dlen);
 	if( (r = inflate(z,Int_val(flush))) < 0 )
 	if( (r = inflate(z,Int_val(flush))) < 0 )
-		failwith("zlib_inflate");
+		caml_failwith("zlib_inflate");
 
 
 	z->next_in = NULL;
 	z->next_in = NULL;
 	z->next_out = NULL;
 	z->next_out = NULL;
 
 
-	res = alloc_small(3, 0);
+	res = caml_alloc_small(3, 0);
 	Field(res, 0) = Val_bool(r == Z_STREAM_END);
 	Field(res, 0) = Val_bool(r == Z_STREAM_END);
 	Field(res, 1) = Val_int(Int_val(slen) - z->avail_in);
 	Field(res, 1) = Val_int(Int_val(slen) - z->avail_in);
 	Field(res, 2) = Val_int(Int_val(dlen) - z->avail_out);
 	Field(res, 2) = Val_int(Int_val(dlen) - z->avail_out);
@@ -348,7 +348,7 @@ CAMLprim value zlib_inflate_bytecode(value * arg, int nargs) {
 
 
 CAMLprim value zlib_inflate_end(value zv) {
 CAMLprim value zlib_inflate_end(value zv) {
 	if( inflateEnd(ZStreamP_val(zv)) != 0 )
 	if( inflateEnd(ZStreamP_val(zv)) != 0 )
-		failwith("zlib_inflate_end");
+		caml_failwith("zlib_inflate_end");
 	return Val_unit;
 	return Val_unit;
 }
 }
 
 
@@ -368,13 +368,13 @@ CAMLprim value executable_path(value u) {
 #ifdef _WIN32
 #ifdef _WIN32
 	char path[MAX_PATH];
 	char path[MAX_PATH];
 	if( GetModuleFileName(NULL,path,MAX_PATH) == 0 )
 	if( GetModuleFileName(NULL,path,MAX_PATH) == 0 )
-		failwith("executable_path");
+		caml_failwith("executable_path");
 	return caml_copy_string(path);
 	return caml_copy_string(path);
 #elif __APPLE__
 #elif __APPLE__
 	char path[MAXPATHLEN+1];
 	char path[MAXPATHLEN+1];
 	uint32_t path_len = MAXPATHLEN;
 	uint32_t path_len = MAXPATHLEN;
 	if ( _NSGetExecutablePath(path, &path_len) )
 	if ( _NSGetExecutablePath(path, &path_len) )
-		failwith("executable_path");
+		caml_failwith("executable_path");
 	return caml_copy_string(path);
 	return caml_copy_string(path);
 #elif __FreeBSD__
 #elif __FreeBSD__
 	char path[PATH_MAX];
 	char path[PATH_MAX];
@@ -387,7 +387,7 @@ CAMLprim value executable_path(value u) {
 	len = sizeof(path);
 	len = sizeof(path);
 	error = sysctl(name, 4, path, &len, NULL, 0);
 	error = sysctl(name, 4, path, &len, NULL, 0);
 	if( error < 0 )
 	if( error < 0 )
-		failwith("executable_path");
+		caml_failwith("executable_path");
 	return caml_copy_string(path);
 	return caml_copy_string(path);
 #else
 #else
 	char path[PATH_MAX];
 	char path[PATH_MAX];
@@ -397,7 +397,7 @@ CAMLprim value executable_path(value u) {
 		if( p != NULL )
 		if( p != NULL )
 			return caml_copy_string(p);
 			return caml_copy_string(p);
 		else
 		else
-			failwith("executable_path");
+			caml_failwith("executable_path");
 	}
 	}
 	path[length] = '\0';
 	path[length] = '\0';
 	return caml_copy_string(path);
 	return caml_copy_string(path);
@@ -408,12 +408,12 @@ CAMLprim value get_full_path( value f ) {
 #ifdef _WIN32
 #ifdef _WIN32
 	char path[MAX_PATH];
 	char path[MAX_PATH];
 	if( GetFullPathName(String_val(f),MAX_PATH,path,NULL) == 0 )
 	if( GetFullPathName(String_val(f),MAX_PATH,path,NULL) == 0 )
-		failwith("get_full_path");
+		caml_failwith("get_full_path");
 	return caml_copy_string(path);
 	return caml_copy_string(path);
 #else
 #else
 	char path[4096];
 	char path[4096];
 	if( realpath(String_val(f),path) == NULL )
 	if( realpath(String_val(f),path) == NULL )
-		failwith("get_full_path");
+		caml_failwith("get_full_path");
 	return caml_copy_string(path);
 	return caml_copy_string(path);
 #endif
 #endif
 }
 }
@@ -428,7 +428,7 @@ CAMLprim value get_real_path( value path ) {
 
 
 	// this will ensure the full class path with proper casing
 	// this will ensure the full class path with proper casing
 	if( GetFullPathName(String_val(path),MAX_PATH,out,NULL) == 0 )
 	if( GetFullPathName(String_val(path),MAX_PATH,out,NULL) == 0 )
-		failwith("get_real_path");
+		caml_failwith("get_real_path");
 
 
 	len = strlen(out);
 	len = strlen(out);
 	i = 0;
 	i = 0;
@@ -501,7 +501,7 @@ CAMLprim value sys_time() {
 		ULARGE_INTEGER ui;
 		ULARGE_INTEGER ui;
 		GetSystemTime(&t);
 		GetSystemTime(&t);
 		if( !SystemTimeToFileTime(&t,&ft) )
 		if( !SystemTimeToFileTime(&t,&ft) )
-			failwith("sys_cpu_time");
+			caml_failwith("sys_cpu_time");
 		ui.LowPart = ft.dwLowDateTime;
 		ui.LowPart = ft.dwLowDateTime;
 		ui.HighPart = ft.dwHighDateTime;
 		ui.HighPart = ft.dwHighDateTime;
 		return caml_copy_double( ((double)ui.QuadPart) / 10000000.0 - EPOCH_DIFF );
 		return caml_copy_double( ((double)ui.QuadPart) / 10000000.0 - EPOCH_DIFF );

+ 2 - 2
libs/extc/process_stubs.c

@@ -67,10 +67,10 @@
 #define val_null Val_int(0)
 #define val_null Val_int(0)
 #define val_some(v) Field(v,0)
 #define val_some(v) Field(v,0)
 #define val_int(v) Int_val(v)
 #define val_int(v) Int_val(v)
-#define neko_error() failwith(__FUNCTION__)
+#define neko_error() caml_failwith(__FUNCTION__)
 
 
 static value alloc_private( int size ) {
 static value alloc_private( int size ) {
-	return alloc((size + sizeof(value) - 1) / sizeof(value), Abstract_tag);
+	return caml_alloc((size + sizeof(value) - 1) / sizeof(value), Abstract_tag);
 }
 }
 
 
 // --- buffer api
 // --- buffer api

+ 7 - 1
libs/extlib-leftovers/dune

@@ -1,7 +1,13 @@
 (include_subdirs no)
 (include_subdirs no)
 
 
+(env
+	(_
+		(flags (-w -3 -w -27 -w -32))
+	)
+)
+
 (library
 (library
 	(name extlib_leftovers)
 	(name extlib_leftovers)
 	(libraries extlib)
 	(libraries extlib)
 	; (wrapped false)
 	; (wrapped false)
-)
+)

+ 5 - 5
libs/extlib-leftovers/multiArray.ml

@@ -77,7 +77,7 @@ let init len f =
 			len = len;
 			len = len;
 			arr = imake 0 0;
 			arr = imake 0 0;
 			darr = Some arr;
 			darr = Some arr;
-		}		
+		}
 	end
 	end
 
 
 let make len e =
 let make len e =
@@ -124,7 +124,7 @@ let set d idx v =
 	| None -> iset (iget d.arr (idx lsr nbits)) (idx land mask) v
 	| None -> iset (iget d.arr (idx lsr nbits)) (idx land mask) v
 	| Some arr -> iset arr idx v
 	| Some arr -> iset arr idx v
 
 
-let rec add d v =
+let add d v =
 	(match d.darr with
 	(match d.darr with
 	| None ->
 	| None ->
 		let asize = ilen d.arr in
 		let asize = ilen d.arr in
@@ -140,7 +140,7 @@ let rec add d v =
 	| Some arr ->
 	| Some arr ->
 		if d.len < ilen arr then begin
 		if d.len < ilen arr then begin
 			(* set *)
 			(* set *)
-			iset arr d.len v;			
+			iset arr d.len v;
 		end else if d.len lsl 1 >= Sys.max_array_length then begin
 		end else if d.len lsl 1 >= Sys.max_array_length then begin
 			(* promote *)
 			(* promote *)
 			let count = (d.len + size) lsr nbits in
 			let count = (d.len + size) lsr nbits in
@@ -180,7 +180,7 @@ let of_list src =
 	let c = create() in
 	let c = create() in
 	List.iter (add c) src;
 	List.iter (add c) src;
 	c
 	c
-	
+
 let iter f d = match d.darr with
 let iter f d = match d.darr with
 	| None ->
 	| None ->
 	 	let max = ilen d.arr - 1 in
 	 	let max = ilen d.arr - 1 in
@@ -281,4 +281,4 @@ let fold_left f acc d = match d.darr with
 		for i = 0 to d.len - 1 do
 		for i = 0 to d.len - 1 do
 			acc := f !acc (iget arr i)
 			acc := f !acc (iget arr i)
 		done;
 		done;
-		!acc
+		!acc

+ 1 - 1
libs/extlib-leftovers/uTF8.ml

@@ -177,7 +177,7 @@ let rec iter_aux proc s i =
 
 
 let iter proc s = iter_aux proc s 0
 let iter proc s = iter_aux proc s 0
 
 
-let compare s1 s2 = Pervasives.compare s1 s2
+let compare s1 s2 = Stdlib.compare s1 s2
 
 
 exception Malformed_code
 exception Malformed_code
 
 

+ 7 - 1
libs/ilib/dune

@@ -1,9 +1,15 @@
 (include_subdirs no)
 (include_subdirs no)
 
 
+(env
+	(_
+		(flags (-w -3 -w -27))
+	)
+)
+
 (library
 (library
 	(name ilib)
 	(name ilib)
 	(modules_without_implementation ilData ilMeta)
 	(modules_without_implementation ilData ilMeta)
 	(modules (:standard \ dump))
 	(modules (:standard \ dump))
 	(libraries extlib)
 	(libraries extlib)
 	(wrapped false)
 	(wrapped false)
-)
+)

+ 2 - 2
libs/ilib/peReader.ml

@@ -25,7 +25,7 @@ open ExtList;;
 exception Error_message of string
 exception Error_message of string
 
 
 type reader_ctx = {
 type reader_ctx = {
-	ch : Pervasives.in_channel;
+	ch : Stdlib.in_channel;
 	i : IO.input;
 	i : IO.input;
 	verbose : bool;
 	verbose : bool;
 }
 }
@@ -42,7 +42,7 @@ let seek r pos =
 	seek_in r.ch pos
 	seek_in r.ch pos
 
 
 let pos r =
 let pos r =
-	Pervasives.pos_in r.ch
+	Stdlib.pos_in r.ch
 
 
 let info r msg =
 let info r msg =
 	if r.verbose then
 	if r.verbose then

+ 7 - 1
libs/javalib/dune

@@ -1,7 +1,13 @@
 (include_subdirs no)
 (include_subdirs no)
 
 
+(env
+	(_
+		(flags (-w -50))
+	)
+)
+
 (library
 (library
 	(name javalib)
 	(name javalib)
 	(libraries extlib)
 	(libraries extlib)
 	(wrapped false)
 	(wrapped false)
-)
+)

+ 7 - 1
libs/neko/dune

@@ -1,7 +1,13 @@
 (include_subdirs no)
 (include_subdirs no)
 
 
+(env
+	(_
+		(flags (-w -27))
+	)
+)
+
 (library
 (library
 	(name neko)
 	(name neko)
 	(libraries extlib)
 	(libraries extlib)
 	(wrapped false)
 	(wrapped false)
-)
+)

+ 2 - 2
libs/neko/ncompile.ml

@@ -673,8 +673,8 @@ and compile_builtin ctx tail b el p =
 			write ctx (Call 1);
 			write ctx (Call 1);
 			(* // insert an infinite loop in order to
 			(* // insert an infinite loop in order to
 			// comply with bytecode checker *)
 			// comply with bytecode checker *)
-			let _ = jmp ctx in
-			()
+			let _jmp = jmp ctx in
+			ignore(_jmp)
 		) dtraps;
 		) dtraps;
 	| ("goto" , _) ->
 	| ("goto" , _) ->
 		error "Invalid $goto statement" p
 		error "Invalid $goto statement" p

+ 27 - 4
libs/objsize/c_objsize.c

@@ -12,6 +12,11 @@
 #include "util.h"
 #include "util.h"
 
 
 #include <caml/memory.h>
 #include <caml/memory.h>
+#include <caml/version.h>
+
+#if OCAML_VERSION_MAJOR >= 5
+#include <caml/address_class.h>
+#endif
 
 
 // FROM byterun/gc.h
 // FROM byterun/gc.h
 #define Caml_white (0 << 8)
 #define Caml_white (0 << 8)
@@ -38,6 +43,7 @@
 #define In_static_data 4
 #define In_static_data 4
 #define In_code_area 8
 #define In_code_area 8
 
 
+#if OCAML_VERSION_MAJOR < 5
 #ifdef ARCH_SIXTYFOUR
 #ifdef ARCH_SIXTYFOUR
 
 
 // 64 bits: Represent page table as a sparse hash table
 // 64 bits: Represent page table as a sparse hash table
@@ -63,6 +69,23 @@ CAMLextern unsigned char * caml_page_table[Pagetable1_size];
 
 
 #define Is_in_heap_or_young(a) (Classify_addr(a) & (In_heap | In_young))
 #define Is_in_heap_or_young(a) (Classify_addr(a) & (In_heap | In_young))
 
 
+void store_explicit(header_t hd, value v, int col)
+ {
+  Hd_val(v) = Coloredhd_hd(hd, col);
+ }
+
+#else
+
+void store_explicit(header_t hd, value v, int col)
+ {
+  atomic_store_explicit(
+	Hp_atomic_val(v),
+	Coloredhd_hd(hd, col),
+	memory_order_release);
+ }
+
+#endif
+
 //--------------------------------------------------------
 //--------------------------------------------------------
 
 
 
 
@@ -352,7 +375,7 @@ void c_rec_objsize(value v, size_t depth)
 
 
   DBG(printf("COL: w %08lx %i\n", v, col));
   DBG(printf("COL: w %08lx %i\n", v, col));
 
 
-  Hd_val(v) = Coloredhd_hd(hd, Col_blue);
+  store_explicit(hd, v, Col_blue);
 
 
   if (Tag_val(v) < No_scan_tag)
   if (Tag_val(v) < No_scan_tag)
    {
    {
@@ -378,7 +401,7 @@ void restore_colors(value v)
 
 
   col = readcolor();
   col = readcolor();
   DBG(printf("COL: r %08lx %i\n", v, col));
   DBG(printf("COL: r %08lx %i\n", v, col));
-  Hd_val(v) = Coloredhd_hd(Hd_val(v), col);
+  store_explicit(Hd_val(v), v, col);
 
 
   if (Tag_val(v) < No_scan_tag)
   if (Tag_val(v) < No_scan_tag)
    {
    {
@@ -417,7 +440,7 @@ int c_objsize(value v, value scan, value reach, size_t* headers, size_t* data, s
 	head = Field(head,1);
 	head = Field(head,1);
 	if( col == Col_blue ) continue;
 	if( col == Col_blue ) continue;
 	writecolor(col);
 	writecolor(col);
-	Hd_val(v) = Coloredhd_hd(hd, Col_blue);
+	store_explicit(hd, v, Col_blue);
  }
  }
 
 
  acc_data = 0;
  acc_data = 0;
@@ -444,7 +467,7 @@ int c_objsize(value v, value scan, value reach, size_t* headers, size_t* data, s
 	head = Field(head,1);
 	head = Field(head,1);
 	if( Colornum_hd(Hd_val(v)) != Col_blue ) continue;
 	if( Colornum_hd(Hd_val(v)) != Col_blue ) continue;
 	col = readcolor();
 	col = readcolor();
-	Hd_val(v) = Coloredhd_hd(Hd_val(v), col);
+	store_explicit(Hd_val(v), v, col);
  }
  }
 
 
   while( COND_BLOCK(reach) ) {
   while( COND_BLOCK(reach) ) {

+ 9 - 6
libs/pcre2/pcre2_stubs.c

@@ -326,7 +326,7 @@ CAMLprim value pcre2_compile_stub(int64_t v_opt, value v_tables, value v_pat)
 
 
 CAMLprim value pcre2_compile_stub_bc(value v_opt, value v_tables, value v_pat)
 CAMLprim value pcre2_compile_stub_bc(value v_opt, value v_tables, value v_pat)
 {
 {
-  return pcre2_compile_stub(Long_val(v_opt), v_tables, v_pat);
+  return pcre2_compile_stub(Int64_val(v_opt), v_tables, v_pat);
 }
 }
 
 
 /* Gets the depth limit of a regular expression if it exists */
 /* Gets the depth limit of a regular expression if it exists */
@@ -338,7 +338,7 @@ CAMLprim value pcre2_compile_stub_bc(value v_opt, value v_tables, value v_pat)
 
 
 /* Sets a match limit for a regular expression imperatively */
 /* Sets a match limit for a regular expression imperatively */
 
 
-CAMLprim value pcre2_set_imp_match_limit_stub(value v_rex, value v_lim) {
+CAMLprim value pcre2_set_imp_match_limit_stub(value v_rex, intnat v_lim) {
   pcre2_match_context* mcontext = get_mcontext(v_rex);
   pcre2_match_context* mcontext = get_mcontext(v_rex);
   pcre2_set_match_limit(mcontext, v_lim);
   pcre2_set_match_limit(mcontext, v_lim);
   return v_rex;
   return v_rex;
@@ -395,12 +395,15 @@ CAMLprim int64_t pcre2_argoptions_stub(value v_rex)
 {
 {
   uint32_t options;
   uint32_t options;
   const int ret = pcre2_pattern_info_stub(v_rex, PCRE2_INFO_ARGOPTIONS, &options);
   const int ret = pcre2_pattern_info_stub(v_rex, PCRE2_INFO_ARGOPTIONS, &options);
-  if (ret != 0) raise_internal_error("pcre2_##name##_stub");
+  if (ret != 0) raise_internal_error("pcre2_argoptions_stub");
   return (int64_t)options;
   return (int64_t)options;
 }
 }
 
 
 CAMLprim value pcre2_argoptions_stub_bc(value v_rex)
 CAMLprim value pcre2_argoptions_stub_bc(value v_rex)
-{ return Val_long(pcre2_argoptions_stub(v_rex)); }
+{
+  CAMLparam1(v_rex);
+  CAMLreturn(caml_copy_int64(pcre2_argoptions_stub(v_rex)));
+}
 
 
 CAMLprim value pcre2_firstcodeunit_stub(value v_rex)
 CAMLprim value pcre2_firstcodeunit_stub(value v_rex)
 {
 {
@@ -627,7 +630,7 @@ CAMLprim value pcre2_match_stub_bc(value *argv, int __unused argn)
 {
 {
   return
   return
     pcre2_match_stub0(
     pcre2_match_stub0(
-        Long_val(argv[0]), argv[1], Int_val(argv[2]), Int_val(argv[3]),
+        Int64_val(argv[0]), argv[1], Int_val(argv[2]), Int_val(argv[3]),
         argv[4], argv[5], argv[6], (value) NULL);
         argv[4], argv[5], argv[6], (value) NULL);
 }
 }
 
 
@@ -637,7 +640,7 @@ CAMLprim value pcre2_dfa_match_stub_bc(value *argv, int __unused argn)
 {
 {
   return
   return
     pcre2_match_stub0(
     pcre2_match_stub0(
-        Long_val(argv[0]), argv[1], Int_val(argv[2]), Int_val(argv[3]),
+        Int64_val(argv[0]), argv[1], Int_val(argv[2]), Int_val(argv[3]),
         argv[4], argv[5], argv[6], argv[7]);
         argv[4], argv[5], argv[6], argv[7]);
 }
 }
 
 

+ 7 - 1
libs/swflib/dune

@@ -1,8 +1,14 @@
 (include_subdirs no)
 (include_subdirs no)
 
 
+(env
+	(_
+		(flags (-w -3 -w -27))
+	)
+)
+
 (library
 (library
 	(name swflib)
 	(name swflib)
 	(libraries extc extlib extlib_leftovers)
 	(libraries extc extlib extlib_leftovers)
 	(modules_without_implementation as3 as3hl)
 	(modules_without_implementation as3 as3hl)
 	(wrapped false)
 	(wrapped false)
-)
+)

+ 1 - 1
libs/swflib/swfParser.ml

@@ -444,7 +444,7 @@ and tag_length t =
 (* READ PRIMS *)
 (* READ PRIMS *)
 
 
 let skip ch n =
 let skip ch n =
-	seek_in ch ((Pervasives.pos_in ch) + n)
+	seek_in ch ((Stdlib.pos_in ch) + n)
 
 
 let read_rgba ch =
 let read_rgba ch =
 	let r = read_byte ch in
 	let r = read_byte ch in

+ 1 - 1
libs/swflib/swfPic.ml

@@ -59,7 +59,7 @@ let load_picture file id =
 	let len = String.length file in
 	let len = String.length file in
 	let p = (try String.rindex file '.' with Not_found -> len) in
 	let p = (try String.rindex file '.' with Not_found -> len) in
 	let ext = String.sub file (p + 1) (len - (p + 1)) in
 	let ext = String.sub file (p + 1) (len - (p + 1)) in
-	match String.uppercase ext with
+	match ExtString.String.uppercase ext with
 	| "PNG" ->
 	| "PNG" ->
 		let png , header, data = (try
 		let png , header, data = (try
 			let p = Png.parse ch in
 			let p = Png.parse ch in

+ 7 - 1
libs/ttflib/dune

@@ -1,8 +1,14 @@
 (include_subdirs no)
 (include_subdirs no)
 
 
+(env
+	(_
+		(flags (-w -3 -w -27 -w -35))
+	)
+)
+
 (library
 (library
 	(name ttflib)
 	(name ttflib)
 	(libraries extlib extlib_leftovers swflib unix)
 	(libraries extlib extlib_leftovers swflib unix)
 	(modules (:standard \ main))
 	(modules (:standard \ main))
 	(wrapped false)
 	(wrapped false)
-)
+)

+ 1 - 1
libs/ttflib/tTFParser.ml

@@ -24,7 +24,7 @@ open TTFData
 open IO
 open IO
 
 
 type ctx = {
 type ctx = {
-	file : Pervasives.in_channel;
+	file : Stdlib.in_channel;
 	ch : input;
 	ch : input;
 	mutable entry : entry;
 	mutable entry : entry;
 }
 }

+ 7 - 1
libs/ziplib/dune

@@ -1,7 +1,13 @@
 (include_subdirs no)
 (include_subdirs no)
 
 
+(env
+	(_
+		(flags (-w -3 -w -27 -w -35 -w -50))
+	)
+)
+
 (library
 (library
 	(name ziplib)
 	(name ziplib)
 	(libraries extc unix)
 	(libraries extc unix)
 	(wrapped false)
 	(wrapped false)
-)
+)

+ 8 - 8
libs/ziplib/zip.ml

@@ -62,7 +62,7 @@ type entry =
 
 
 type in_file =
 type in_file =
   { if_filename: string;
   { if_filename: string;
-    if_channel: Pervasives.in_channel;
+    if_channel: Stdlib.in_channel;
     if_entries: entry list;
     if_entries: entry list;
     if_directory: (string, entry) Hashtbl.t;
     if_directory: (string, entry) Hashtbl.t;
     if_comment: string }
     if_comment: string }
@@ -72,7 +72,7 @@ let comment ifile = ifile.if_comment
 
 
 type out_file =
 type out_file =
   { of_filename: string;
   { of_filename: string;
-    of_channel: Pervasives.out_channel;
+    of_channel: Stdlib.out_channel;
     mutable of_entries: entry list;
     mutable of_entries: entry list;
     of_comment: string }
     of_comment: string }
 
 
@@ -217,7 +217,7 @@ let read_cd filename ic cd_entries cd_offset cd_bound =
 (* Open a ZIP file for reading *)
 (* Open a ZIP file for reading *)
 
 
 let open_in filename =
 let open_in filename =
-  let ic = Pervasives.open_in_bin filename in
+  let ic = Stdlib.open_in_bin filename in
   let (cd_entries, cd_size, cd_offset, cd_comment) = read_ecd filename ic in
   let (cd_entries, cd_size, cd_offset, cd_comment) = read_ecd filename ic in
   let entries =
   let entries =
     read_cd filename ic cd_entries cd_offset (Int32.add cd_offset cd_size) in
     read_cd filename ic cd_entries cd_offset (Int32.add cd_offset cd_size) in
@@ -232,7 +232,7 @@ let open_in filename =
 (* Close a ZIP file opened for reading *)
 (* Close a ZIP file opened for reading *)
 
 
 let close_in ifile =
 let close_in ifile =
-  Pervasives.close_in ifile.if_channel
+  Stdlib.close_in ifile.if_channel
 
 
 (* Return the info associated with an entry *)
 (* Return the info associated with an entry *)
 
 
@@ -369,7 +369,7 @@ let open_out ?(comment = "") filename =
   if String.length comment >= 0x10000 then
   if String.length comment >= 0x10000 then
     raise(Error(filename, "", "comment too long"));
     raise(Error(filename, "", "comment too long"));
   { of_filename = filename;
   { of_filename = filename;
-    of_channel = Pervasives.open_out_bin filename;
+    of_channel = Stdlib.open_out_bin filename;
     of_entries = [];
     of_entries = [];
     of_comment = comment }
     of_comment = comment }
 
 
@@ -416,7 +416,7 @@ let close_out ofile =
   write4_int oc start_cd;               (* offset of central dir *)
   write4_int oc start_cd;               (* offset of central dir *)
   write2 oc (String.length ofile.of_comment); (* length of comment *)
   write2 oc (String.length ofile.of_comment); (* length of comment *)
   writestring oc ofile.of_comment;         (* comment *)
   writestring oc ofile.of_comment;         (* comment *)
-  Pervasives.close_out oc
+  Stdlib.close_out oc
 
 
 (* Write a local file header and return the corresponding entry *)
 (* Write a local file header and return the corresponding entry *)
 
 
@@ -552,9 +552,9 @@ let copy_file_to_entry infilename ofile ?(extra = "") ?(comment = "")
         with Unix.Unix_error(_,_,_) -> None in
         with Unix.Unix_error(_,_,_) -> None in
   try
   try
     copy_channel_to_entry ic ofile ~extra ~comment ~level ?mtime:mtime' name;
     copy_channel_to_entry ic ofile ~extra ~comment ~level ?mtime:mtime' name;
-    Pervasives.close_in ic
+    Stdlib.close_in ic
   with x ->
   with x ->
-    Pervasives.close_in ic; raise x
+    Stdlib.close_in ic; raise x
 
 
 
 
 (* Add an entry whose content will be produced by the caller *)
 (* Add an entry whose content will be produced by the caller *)

+ 7 - 1
plugins/example/dune

@@ -1,7 +1,13 @@
 (data_only_dirs cmxs hx)
 (data_only_dirs cmxs hx)
 (include_subdirs unqualified)
 (include_subdirs unqualified)
 
 
+(env
+	(_
+		(flags -w -27 -w -50)
+	)
+)
+
 (library
 (library
 	(name example)
 	(name example)
 	(libraries haxe)
 	(libraries haxe)
-)
+)

+ 199 - 37
src-json/define.json

@@ -8,7 +8,8 @@
 		"name": "AdvancedTelemetry",
 		"name": "AdvancedTelemetry",
 		"define": "advanced-telemetry",
 		"define": "advanced-telemetry",
 		"doc": "Allow the SWF to be measured with Monocle tool.",
 		"doc": "Allow the SWF to be measured with Monocle tool.",
-		"platforms": ["flash"]
+		"platforms": ["flash"],
+		"deprecated": "The flash target will be removed for Haxe 5"
 	},
 	},
 	{
 	{
 		"name": "AnalyzerOptimize",
 		"name": "AnalyzerOptimize",
@@ -199,7 +200,8 @@
 		"name": "Fdb",
 		"name": "Fdb",
 		"define": "fdb",
 		"define": "fdb",
 		"doc": "Enable full flash debug infos for FDB interactive debugging.",
 		"doc": "Enable full flash debug infos for FDB interactive debugging.",
-		"platforms": ["flash"]
+		"platforms": ["flash"],
+		"deprecated": "The flash target will be removed for Haxe 5"
 	},
 	},
 	{
 	{
 		"name": "FileExtension",
 		"name": "FileExtension",
@@ -211,13 +213,15 @@
 		"name": "FlashStrict",
 		"name": "FlashStrict",
 		"define": "flash-strict",
 		"define": "flash-strict",
 		"doc": "More strict typing for flash target.",
 		"doc": "More strict typing for flash target.",
-		"platforms": ["flash"]
+		"platforms": ["flash"],
+		"deprecated": "The flash target will be removed for Haxe 5"
 	},
 	},
 	{
 	{
 		"name": "FlashUseStage",
 		"name": "FlashUseStage",
 		"define": "flash-use-stage",
 		"define": "flash-use-stage",
 		"doc": "Keep the SWF library initial stage.",
 		"doc": "Keep the SWF library initial stage.",
-		"platforms": ["flash"]
+		"platforms": ["flash"],
+		"deprecated": "The flash target will be removed for Haxe 5"
 	},
 	},
 	{
 	{
 		"devcomment": "force-lib-check is only here as a debug facility - compiler checking allows errors to be found more easily",
 		"devcomment": "force-lib-check is only here as a debug facility - compiler checking allows errors to be found more easily",
@@ -241,13 +245,15 @@
 	{
 	{
 		"name": "Haxe3Compat",
 		"name": "Haxe3Compat",
 		"define": "haxe3compat",
 		"define": "haxe3compat",
-		"doc": "Gives warnings about transition from Haxe 3.x to Haxe 4.0."
+		"doc": "Gives warnings about transition from Haxe 3.x to Haxe 4.0.",
+		"deprecated": "This flag is no longer supported in Haxe 5"
 	},
 	},
 	{
 	{
 		"name": "HaxeBoot",
 		"name": "HaxeBoot",
 		"define": "haxe-boot",
 		"define": "haxe-boot",
 		"doc": "Give the name 'haxe' to the flash boot class instead of a generated name.",
 		"doc": "Give the name 'haxe' to the flash boot class instead of a generated name.",
-		"platforms": ["flash"]
+		"platforms": ["flash"],
+		"deprecated": "The flash target will be removed for Haxe 5"
 	},
 	},
 	{
 	{
 		"name": "HaxeVer",
 		"name": "HaxeVer",
@@ -261,6 +267,32 @@
 		"doc": "The current Haxe version value in SemVer format.",
 		"doc": "The current Haxe version value in SemVer format.",
 		"reserved": true
 		"reserved": true
 	},
 	},
+	{
+		"name": "HaxeNext",
+		"define": "haxe-next",
+		"doc": "Enable experimental features that are meant to be released on next Haxe version."
+	},
+	{
+		"name": "HaxeOutputFile",
+		"define": "HAXE_OUTPUT_FILE",
+		"doc": "Force the full output name of the executable/library without library prefix and debug suffix.",
+		"platforms": ["cpp"],
+		"params": ["name"]
+	},
+	{
+		"name": "HaxeOutputPart",
+		"define": "HAXE_OUTPUT_PART",
+		"doc": "Output name of the executable/library. (default: main class name)",
+		"platforms": ["cpp"],
+		"params": ["name"]
+	},
+	{
+		"name": "Hlc",
+		"define": "hlc",
+		"doc": "Defined by compiler when using hl/c target.",
+		"platforms": ["hl"],
+		"reserved": true
+	},
 	{
 	{
 		"name": "HlVer",
 		"name": "HlVer",
 		"define": "hl-ver",
 		"define": "hl-ver",
@@ -287,6 +319,114 @@
 		"doc": "Include additional information for hxcpp-debugger.",
 		"doc": "Include additional information for hxcpp-debugger.",
 		"platforms": ["cpp"]
 		"platforms": ["cpp"]
 	},
 	},
+	{
+		"name": "HxcppGcMoving",
+		"define": "HXCPP-GC-MOVING",
+		"doc": "Allow garbage collector to move memory to reduce fragmentation",
+		"platforms": ["cpp"]
+	},
+	{
+		"name": "HxcppGcSummary",
+		"define": "HXCPP-GC-SUMMARY",
+		"doc": "Print small profiling summary at end of program",
+		"platforms": ["cpp"]
+	},
+	{
+		"name": "HxcppGcDynamicSize",
+		"define": "HXCPP-GC-DYNAMIC-SIZE",
+		"doc": "Monitor GC times and expand memory working space if required",
+		"platforms": ["cpp"]
+	},
+	{
+		"name": "HxcppGcBigBlocks",
+		"define": "HXCPP-GC-BIG-BLOCKS",
+		"doc": "Allow working memory greater than 1 Gig",
+		"platforms": ["cpp"]
+	},
+	{
+		"name": "HxcppGcDebugLevel",
+		"define": "HXCPP-GC-DEBUG-LEVEL",
+		"doc": "Number 1-4 indicating additional debugging in GC",
+		"platforms": ["cpp"]
+	},
+	{
+		"name": "HxcppDebugLink",
+		"define": "HXCPP-DEBUG-LINK",
+		"doc": "Add symbols to final binary, even in release mode.",
+		"platforms": ["cpp"]
+	},
+	{
+		"name": "HxcppStackTrace",
+		"define": "HXCPP-STACK-TRACE",
+		"doc": "Have valid function-level stack traces, even in release mode.",
+		"platforms": ["cpp"]
+	},
+	{
+		"name": "HxcppStackLine",
+		"define": "HXCPP-STACK-LINE",
+		"doc": "Include line information in stack traces, even in release mode.",
+		"platforms": ["cpp"]
+	},
+	{
+		"name": "HxcppCheckPointer",
+		"define": "HXCPP-CHECK-POINTER",
+		"doc": "Add null-pointer checks, even in release mode.",
+		"platforms": ["cpp"]
+	},
+	{
+		"name": "HxcppProfiler",
+		"define": "HXCPP-PROFILER",
+		"doc": "Add profiler support",
+		"platforms": ["cpp"]
+	},
+	{
+		"name": "HxcppTelemetry",
+		"define": "HXCPP-TELEMETRY",
+		"doc": "Add telemetry support",
+		"platforms": ["cpp"]
+	},
+	{
+		"name": "HxcppCpp11",
+		"define": "HXCPP-CPP11",
+		"doc": "Use C++11 features and link libraries",
+		"platforms": ["cpp"]
+	},
+	{
+		"name": "HxcppVerbose",
+		"define": "HXCPP-VERBOSE",
+		"doc": "Print extra output from build tool.",
+		"platforms": ["cpp"]
+	},
+	{
+		"name": "HxcppTimes",
+		"define": "HXCPP-TIMES",
+		"doc": "Show some basic profiling information",
+		"platforms": ["cpp"]
+	},
+	{
+		"name": "HxcppM32",
+		"define": "HXCPP-M32",
+		"doc": "Force 32-bit compile for current desktop",
+		"platforms": ["cpp"]
+	},
+	{
+		"name": "HxcppM64",
+		"define": "HXCPP-M64",
+		"doc": "Force 64-bit compile for current desktop",
+		"platforms": ["cpp"]
+	},
+	{
+		"name": "HxcppArm64",
+		"define": "HXCPP-ARM64",
+		"doc": "Compile arm-based devices for 64 bits",
+		"platforms": ["cpp"]
+	},
+	{
+		"name": "HxcppLinuxArm64",
+		"define": "HXCPP-LINUX-ARM64",
+		"doc": "Run on a linux ARM64 device",
+		"platforms": ["cpp"]
+	},
 	{
 	{
 		"name": "HxcppSmartStings",
 		"name": "HxcppSmartStings",
 		"define": "hxcpp-smart-strings",
 		"define": "hxcpp-smart-strings",
@@ -308,7 +448,8 @@
 		"name": "JarLegacyLoader",
 		"name": "JarLegacyLoader",
 		"define": "jar-legacy-loader",
 		"define": "jar-legacy-loader",
 		"doc": "Use the legacy loader to load .jar files on the JVM target.",
 		"doc": "Use the legacy loader to load .jar files on the JVM target.",
-		"platforms": ["java"]
+		"platforms": ["java"],
+		"deprecated": "The legacy JAR loader will be removed in Haxe 5"
 	},
 	},
 	{
 	{
 		"name": "JavaVer",
 		"name": "JavaVer",
@@ -397,12 +538,6 @@
 		"doc": "Enable the jit compiler for lua (version 5.2 only).",
 		"doc": "Enable the jit compiler for lua (version 5.2 only).",
 		"platforms": ["lua"]
 		"platforms": ["lua"]
 	},
 	},
-	{
-		"name": "LuaStandalone",
-		"define": "lua-standalone",
-		"doc": "Print uncaught error before exiting the lua script.",
-		"platforms": ["lua"]
-	},
 	{
 	{
 		"name": "LuaVanilla",
 		"name": "LuaVanilla",
 		"define": "lua-vanilla",
 		"define": "lua-vanilla",
@@ -455,6 +590,14 @@
 		"doc": "Output neko source instead of bytecode.",
 		"doc": "Output neko source instead of bytecode.",
 		"platforms": ["neko"]
 		"platforms": ["neko"]
 	},
 	},
+	{
+		"name": "NekoNoHaxelibPaths",
+		"define": "neko-no-haxelib-paths",
+		"doc": "Disable hard-coded Haxelib ndll paths.",
+		"platforms": [
+			"neko"
+		]
+	},
 	{
 	{
 		"name": "NekoV1",
 		"name": "NekoV1",
 		"define": "neko-v1",
 		"define": "neko-v1",
@@ -465,7 +608,8 @@
 		"name": "NetworkSandbox",
 		"name": "NetworkSandbox",
 		"define": "network-sandbox",
 		"define": "network-sandbox",
 		"doc": "Use local network sandbox instead of local file access one.",
 		"doc": "Use local network sandbox instead of local file access one.",
-		"platforms": ["flash"]
+		"platforms": ["flash"],
+		"deprecated": "The flash target will be removed for Haxe 5"
 	},
 	},
 	{
 	{
 		"name": "NoCompilation",
 		"name": "NoCompilation",
@@ -487,7 +631,8 @@
 		"name": "NoFlashOverride",
 		"name": "NoFlashOverride",
 		"define": "no-flash-override",
 		"define": "no-flash-override",
 		"doc": "Change overrides on some basic classes into HX suffixed methods",
 		"doc": "Change overrides on some basic classes into HX suffixed methods",
-		"platforms": ["flash"]
+		"platforms": ["flash"],
+		"deprecated": "The flash target will be removed for Haxe 5"
 	},
 	},
 	{
 	{
 		"name": "NoOpt",
 		"name": "NoOpt",
@@ -521,7 +666,8 @@
 		"name": "NoSwfCompress",
 		"name": "NoSwfCompress",
 		"define": "no-swf-compress",
 		"define": "no-swf-compress",
 		"doc": "Disable SWF output compression.",
 		"doc": "Disable SWF output compression.",
-		"platforms": ["flash"]
+		"platforms": ["flash"],
+		"deprecated": "The flash target will be removed for Haxe 5"
 	},
 	},
 	{
 	{
 		"name": "NoTraces",
 		"name": "NoTraces",
@@ -624,71 +770,82 @@
 		"define": "swc",
 		"define": "swc",
 		"doc": "Output a SWC instead of a SWF.",
 		"doc": "Output a SWC instead of a SWF.",
 		"platforms": ["flash"],
 		"platforms": ["flash"],
-		"reserved": true
+		"reserved": true,
+		"deprecated": "The flash target will be removed for Haxe 5"
 	},
 	},
 	{
 	{
 		"name": "SwfCompressLevel",
 		"name": "SwfCompressLevel",
 		"define": "swf-compress-level",
 		"define": "swf-compress-level",
 		"doc": "Set the amount of compression for the SWF output.",
 		"doc": "Set the amount of compression for the SWF output.",
 		"platforms": ["flash"],
 		"platforms": ["flash"],
-		"params": ["level: 1-9"]
+		"params": ["level: 1-9"],
+		"deprecated": "The flash target will be removed for Haxe 5"
 	},
 	},
 	{
 	{
 		"name": "SwfDebugPassword",
 		"name": "SwfDebugPassword",
 		"define": "swf-debug-password",
 		"define": "swf-debug-password",
 		"doc": "Set a password for debugging.",
 		"doc": "Set a password for debugging.",
 		"platforms": ["flash"],
 		"platforms": ["flash"],
-		"params": ["password"]
+		"params": ["password"],
+		"deprecated": "The flash target will be removed for Haxe 5"
 	},
 	},
 	{
 	{
 		"name": "SwfDirectBlit",
 		"name": "SwfDirectBlit",
 		"define": "swf-direct-blit",
 		"define": "swf-direct-blit",
 		"doc": "Use hardware acceleration to blit graphics.",
 		"doc": "Use hardware acceleration to blit graphics.",
-		"platforms": ["flash"]
+		"platforms": ["flash"],
+		"deprecated": "The flash target will be removed for Haxe 5"
 	},
 	},
 	{
 	{
 		"name": "SwfGpu",
 		"name": "SwfGpu",
 		"define": "swf-gpu",
 		"define": "swf-gpu",
 		"doc": "Use GPU compositing features when drawing graphics.",
 		"doc": "Use GPU compositing features when drawing graphics.",
-		"platforms": ["flash"]
+		"platforms": ["flash"],
+		"deprecated": "The flash target will be removed for Haxe 5"
 	},
 	},
 	{
 	{
 		"name": "SwfHeader",
 		"name": "SwfHeader",
 		"define": "swf-header",
 		"define": "swf-header",
 		"doc": "define SWF header (width:height:fps:color)",
 		"doc": "define SWF header (width:height:fps:color)",
-		"platforms": ["flash"]
+		"platforms": ["flash"],
+		"deprecated": "The flash target will be removed for Haxe 5"
 	},
 	},
 	{
 	{
 		"name": "SwfMetadata",
 		"name": "SwfMetadata",
 		"define": "swf-metadata",
 		"define": "swf-metadata",
 		"doc": "Include contents of the given file as metadata in the SWF.",
 		"doc": "Include contents of the given file as metadata in the SWF.",
 		"platforms": ["flash"],
 		"platforms": ["flash"],
-		"params": ["file"]
+		"params": ["file"],
+		"deprecated": "The flash target will be removed for Haxe 5"
 	},
 	},
 	{
 	{
 		"name": "SwfPreloaderFrame",
 		"name": "SwfPreloaderFrame",
 		"define": "swf-preloader-frame",
 		"define": "swf-preloader-frame",
 		"doc": "Insert empty first frame in SWF.",
 		"doc": "Insert empty first frame in SWF.",
-		"platforms": ["flash"]
+		"platforms": ["flash"],
+		"deprecated": "The flash target will be removed for Haxe 5"
 	},
 	},
 	{
 	{
 		"name": "SwfProtected",
 		"name": "SwfProtected",
 		"define": "swf-protected",
 		"define": "swf-protected",
 		"doc": "Compile Haxe `private` as `protected` in the SWF instead of `public`.",
 		"doc": "Compile Haxe `private` as `protected` in the SWF instead of `public`.",
-		"platforms": ["flash"]
+		"platforms": ["flash"],
+		"deprecated": "The flash target will be removed for Haxe 5"
 	},
 	},
 	{
 	{
 		"name": "SwfScriptTimeout",
 		"name": "SwfScriptTimeout",
 		"define": "swf-script-timeout",
 		"define": "swf-script-timeout",
 		"doc": "Maximum ActionScript processing time before script stuck dialog box displays.",
 		"doc": "Maximum ActionScript processing time before script stuck dialog box displays.",
 		"platforms": ["flash"],
 		"platforms": ["flash"],
-		"params": ["time in seconds"]
+		"params": ["time in seconds"],
+		"deprecated": "The flash target will be removed for Haxe 5"
 	},
 	},
 	{
 	{
 		"name": "SwfUseDoAbc",
 		"name": "SwfUseDoAbc",
 		"define": "swf-use-doabc",
 		"define": "swf-use-doabc",
 		"doc": "Use `DoAbc` SWF-tag instead of `DoAbcDefine`.",
 		"doc": "Use `DoAbc` SWF-tag instead of `DoAbcDefine`.",
-		"platforms": ["flash"]
+		"platforms": ["flash"],
+		"deprecated": "The flash target will be removed for Haxe 5"
 	},
 	},
 	{
 	{
 		"name": "Sys",
 		"name": "Sys",
@@ -732,24 +889,29 @@
 	},
 	},
 	{
 	{
 		"name": "MessageReporting",
 		"name": "MessageReporting",
-		"define": "message-reporting",
+		"define": "message.reporting",
 		"doc": "Select message reporting mode for compiler output. (default: classic)",
 		"doc": "Select message reporting mode for compiler output. (default: classic)",
 		"params": ["mode: classic | pretty | indent"]
 		"params": ["mode: classic | pretty | indent"]
 	},
 	},
 	{
 	{
-		"name": "NoColor",
-		"define": "no-color",
-		"doc": "Disable ANSI color codes when using rich output."
+		"name": "MessageNoColor",
+		"define": "message.no-color",
+		"doc": "Disable ANSI color codes in message reporting."
+	},
+	{
+		"name": "MessageAbsolutePositions",
+		"define": "message.absolute-positions",
+		"doc": "Use absolute character positions instead of line/columns for message reporting."
 	},
 	},
 	{
 	{
-		"name": "MessagesLogFile",
-		"define": "messages-log-file",
-		"doc": "Path to a text file to write messages log to, in addition to regular output."
+		"name": "MessageLogFile",
+		"define": "message.log-file",
+		"doc": "Path to a text file to write message reporting to, in addition to regular output."
 	},
 	},
 	{
 	{
-		"name": "MessagesLogFormat",
-		"define": "messages-log-format",
-		"doc": "Select message reporting mode for messages log output. (default: indent)",
+		"name": "MessageLogFormat",
+		"define": "message.log-format",
+		"doc": "Select message reporting mode for message log file. (default: indent)",
 		"params": ["format: classic | pretty | indent"]
 		"params": ["format: classic | pretty | indent"]
 	}
 	}
 ]
 ]

+ 2 - 1
src-json/meta.json

@@ -41,7 +41,8 @@
 	{
 	{
 		"name": "Annotation",
 		"name": "Annotation",
 		"metadata": ":annotation",
 		"metadata": ":annotation",
-		"doc": "Annotation (`@interface`) definitions on `--java-lib` imports will be annotated with this metadata. Has no effect on types compiled by Haxe.",
+		"doc": "Marks a class as a Java annotation",
+		"params": ["Retention policy"],
 		"platforms": ["java"],
 		"platforms": ["java"],
 		"targets": ["TClass"]
 		"targets": ["TClass"]
 	},
 	},

+ 10 - 0
src-json/warning.json

@@ -58,6 +58,16 @@
 		"name": "WDeprecated",
 		"name": "WDeprecated",
 		"doc": "This is deprecated and should no longer be used"
 		"doc": "This is deprecated and should no longer be used"
 	},
 	},
+	{
+		"name": "WDeprecatedDefine",
+		"doc": "This define is deprecated and should no longer be used",
+		"parent": "WDeprecated"
+	},
+	{
+		"name": "WDeprecatedEnumAbstract",
+		"doc": "`@:enum abstract` is deprecated, `enum abstract` should be used instead",
+		"parent": "WDeprecated"
+	},
 	{
 	{
 		"name": "WVarInit",
 		"name": "WVarInit",
 		"doc": "A local variable might be used before being assigned a value",
 		"doc": "A local variable might be used before being assigned a value",

+ 7 - 1
src-prebuild/dune

@@ -1,8 +1,14 @@
 (include_subdirs no)
 (include_subdirs no)
 
 
+(env
+	(_
+		(flags (-w -9 -w -32))
+	)
+)
+
 (executable
 (executable
 	(name prebuild)
 	(name prebuild)
 	(public_name haxe_prebuild)
 	(public_name haxe_prebuild)
 	(package haxe_prebuild)
 	(package haxe_prebuild)
 	(libraries extlib json)
 	(libraries extlib json)
-)
+)

+ 68 - 28
src-prebuild/prebuild.ml

@@ -9,6 +9,17 @@ type parsed_warning = {
 	w_generic : bool;
 	w_generic : bool;
 }
 }
 
 
+type parsed_meta = {
+	m_name : string;
+	m_meta : string;
+	m_doc : string;
+	m_params : string list;
+	m_platforms : string list;
+	m_targets : string list;
+	m_internal : bool;
+	m_links : string list;
+}
+
 let as_string = function
 let as_string = function
 	| JString s -> Some s
 	| JString s -> Some s
 	| _ -> None
 	| _ -> None
@@ -104,21 +115,24 @@ let parse_define json =
 	(* doc *) get_field "doc" as_string fields,
 	(* doc *) get_field "doc" as_string fields,
 	(* params *) get_optional_field "params" as_params [] fields,
 	(* params *) get_optional_field "params" as_params [] fields,
 	(* platforms *) get_optional_field "platforms" as_platforms [] fields,
 	(* platforms *) get_optional_field "platforms" as_platforms [] fields,
-	(* links *) get_optional_field "links" as_links [] fields
+	(* links *) get_optional_field "links" as_links [] fields,
+	(* deprecated *) get_optional_field2 "deprecated" as_string fields
 
 
 let parse_meta json =
 let parse_meta json =
 	let fields = match json with
 	let fields = match json with
 		| JObject fl -> fl
 		| JObject fl -> fl
 		| _ -> raise (Prebuild_error "not an object")
 		| _ -> raise (Prebuild_error "not an object")
 	in
 	in
-	(* name *) get_field "name" as_string fields,
-	(* metadata *) get_field "metadata" as_string fields,
-	(* doc *) get_field "doc" as_string fields,
-	(* params *) get_optional_field "params" as_params [] fields,
-	(* platforms *) get_optional_field "platforms" as_platforms [] fields,
-	(* targets *) get_optional_field "targets" as_targets [] fields,
-	(* internal *) get_optional_field "internal" as_bool false fields,
-	(* links *) get_optional_field "links" as_links [] fields
+	{
+		m_name = get_field "name" as_string fields;
+		m_meta = get_field "metadata" as_string fields;
+		m_doc = get_field "doc" as_string fields;
+		m_params = get_optional_field "params" as_params [] fields;
+		m_platforms = get_optional_field "platforms" as_platforms [] fields;
+		m_targets = get_optional_field "targets" as_targets [] fields;
+		m_internal = get_optional_field "internal" as_bool false fields;
+		m_links = get_optional_field "links" as_links [] fields
+	}
 
 
 let parse_warning json =
 let parse_warning json =
 	let fields = match json with
 	let fields = match json with
@@ -165,42 +179,54 @@ let gen_params = List.map (function param -> "HasParam \"" ^ param ^ "\"" )
 let gen_links = List.map (function link -> "Link \"" ^ link ^ "\"" )
 let gen_links = List.map (function link -> "Link \"" ^ link ^ "\"" )
 
 
 let gen_define_type defines =
 let gen_define_type defines =
-	String.concat "\n" (List.map (function (name, _, _, _, _, _) -> "\t| " ^ name) defines)
+	String.concat "\n" (List.map (function (name, _, _, _, _, _, _) -> "\t| " ^ name) defines)
+
+let gen_option f = function
+	| None -> "None"
+	| Some x -> Printf.sprintf "Some(%s)" (f x)
 
 
 let gen_define_info defines =
 let gen_define_info defines =
+	let deprecations = DynArray.create() in
 	let define_str = List.map (function
 	let define_str = List.map (function
-		(name, define, doc, params, platforms, links) ->
+		(name, define, doc, params, platforms, links, deprecated) ->
 			let platforms_str = gen_platforms platforms in
 			let platforms_str = gen_platforms platforms in
 			let params_str = gen_params params in
 			let params_str = gen_params params in
 			let links_str = gen_links links in
 			let links_str = gen_links links in
 			let define = String.concat "_" (ExtString.String.nsplit define "-") in
 			let define = String.concat "_" (ExtString.String.nsplit define "-") in
-			"\t| " ^ name ^ " -> \"" ^ define ^ "\",(" ^ (Printf.sprintf "%S" doc) ^ ",[" ^ (String.concat "; " (platforms_str @ params_str @ links_str)) ^ "])"
+			let deprecated = match deprecated with
+				| None ->
+					[]
+				| Some x ->
+					let quoted = Printf.sprintf "%S" x in
+					DynArray.add deprecations (Printf.sprintf "\t(%S,%S)" define x);
+					[Printf.sprintf "Deprecated(%s)" quoted]
+			in
+			"\t| " ^ name ^ " -> \"" ^ define ^ "\",(" ^ (Printf.sprintf "%S" doc) ^ ",[" ^ (String.concat "; " (platforms_str @ params_str @ links_str @ deprecated)) ^ "])"
 	) defines in
 	) defines in
-	String.concat "\n" define_str
+	String.concat "\n" define_str,String.concat ";\n" (DynArray.to_list deprecations)
 
 
 let gen_meta_type metas =
 let gen_meta_type metas =
 	String.concat "\n" (List.map (function
 	String.concat "\n" (List.map (function
-		| ("InlineConstructorArgument", _, _, _, _, _, _, _) -> "\t| InlineConstructorArgument of int * int"
-		| (name, _, _, _, _, _, _, _) -> "\t| " ^ name
+		| {m_name = "InlineConstructorArgument"} -> "\t| InlineConstructorArgument of int * int"
+		| {m_name = name} -> "\t| " ^ name
 	) metas)
 	) metas)
 
 
 let gen_meta_info metas =
 let gen_meta_info metas =
-	let meta_str = List.map (function
-		(name, metadata, doc, params, platforms, targets, internal, links) ->
-			let platforms_str = gen_platforms platforms in
-			let params_str = gen_params params in
-			let targets_str = (match targets with
+	let meta_str = List.map (function meta ->
+			let platforms_str = gen_platforms meta.m_platforms in
+			let params_str = gen_params meta.m_params in
+			let targets_str = (match meta.m_targets with
 				| [] -> []
 				| [] -> []
 				| targets -> ["UsedOn [" ^ (String.concat ";" targets) ^ "]"]
 				| targets -> ["UsedOn [" ^ (String.concat ";" targets) ^ "]"]
 			) in
 			) in
-			let internal_str = if internal then ["UsedInternally"] else [] in
-			let links_str = gen_links links in
-			let name = (match name with
+			let internal_str = if meta.m_internal then ["UsedInternally"] else [] in
+			let links_str = gen_links meta.m_links in
+			let name = (match meta.m_name with
 				(* this is a hacky, I know *)
 				(* this is a hacky, I know *)
 				| "InlineConstructorArgument" -> "InlineConstructorArgument _"
 				| "InlineConstructorArgument" -> "InlineConstructorArgument _"
-				| _ -> name
+				| _ -> meta.m_name
 			) in
 			) in
-			"\t| " ^ name ^ " -> \"" ^ metadata ^ "\",(" ^ (Printf.sprintf "%S" doc) ^ ",[" ^ (String.concat "; " (platforms_str @ params_str @ targets_str @ internal_str @ links_str)) ^ "])"
+			"\t| " ^ name ^ " -> \"" ^ meta.m_meta ^ "\",(" ^ (Printf.sprintf "%S" meta.m_doc) ^ ",[" ^ (String.concat "; " (platforms_str @ params_str @ targets_str @ internal_str @ links_str)) ^ "])"
 	) metas in
 	) metas in
 	String.concat "\n" meta_str
 	String.concat "\n" meta_str
 
 
@@ -241,7 +267,7 @@ type define_parameter =
 	| HasParam of string
 	| HasParam of string
 	| Platforms of platform list
 	| Platforms of platform list
 	| Link of string
 	| Link of string
-
+	| Deprecated of string
 "
 "
 
 
 let meta_header = autogen_header ^ "
 let meta_header = autogen_header ^ "
@@ -272,6 +298,18 @@ let parse_meta_usage = function
 	| \"TVariable\" -> TVariable
 	| \"TVariable\" -> TVariable
 	| t -> raise (failwith (\"invalid metadata target \" ^ t))
 	| t -> raise (failwith (\"invalid metadata target \" ^ t))
 
 
+let print_meta_usage = function
+	| TClass -> \"TClass\"
+	| TClassField -> \"TClassField\"
+	| TAbstract -> \"TAbstract\"
+	| TAbstractField -> \"TAbstractField\"
+	| TEnum -> \"TEnum\"
+	| TTypedef -> \"TTypedef\"
+	| TAnyField -> \"TAnyField\"
+	| TExpr -> \"TExpr\"
+	| TTypeParameter -> \"TTypeParameter\"
+	| TVariable -> \"TVariable\"
+
 type meta_parameter =
 type meta_parameter =
 	| HasParam of string
 	| HasParam of string
 	| Platforms of platform list
 	| Platforms of platform list
@@ -290,9 +328,11 @@ match Array.to_list (Sys.argv) with
 		Printf.printf "type strict_defined =\n";
 		Printf.printf "type strict_defined =\n";
 		Printf.printf "%s" (gen_define_type defines);
 		Printf.printf "%s" (gen_define_type defines);
 		Printf.printf "\n\t| Last\n\t| Custom of string\n\n";
 		Printf.printf "\n\t| Last\n\t| Custom of string\n\n";
+		let infos,deprecations = gen_define_info defines in
 		Printf.printf "let infos = function\n";
 		Printf.printf "let infos = function\n";
-		Printf.printf "%s" (gen_define_info defines);
-		Printf.printf "\n\t| Last -> die \"\" __LOC__\n\t| Custom s -> s,(\"\",[])\n"
+		Printf.printf "%s" infos;
+		Printf.printf "\n\t| Last -> die \"\" __LOC__\n\t| Custom s -> s,(\"\",[])\n";
+		Printf.printf "\nlet deprecated_defines = [\n%s\n]\n" deprecations;
 	| [_; "meta"; meta_path]->
 	| [_; "meta"; meta_path]->
 		let metas = parse_file_array meta_path parse_meta in
 		let metas = parse_file_array meta_path parse_meta in
 		Printf.printf "%s" meta_header;
 		Printf.printf "%s" meta_header;

+ 24 - 24
src/codegen/codegen.ml

@@ -20,7 +20,6 @@
 open Ast
 open Ast
 open Type
 open Type
 open Common
 open Common
-open Error
 open Globals
 open Globals
 open Extlib_leftovers
 open Extlib_leftovers
 
 
@@ -66,12 +65,12 @@ let add_property_field com c =
 		c.cl_statics <- PMap.add cf.cf_name cf c.cl_statics;
 		c.cl_statics <- PMap.add cf.cf_name cf c.cl_statics;
 		c.cl_ordered_statics <- cf :: c.cl_ordered_statics
 		c.cl_ordered_statics <- cf :: c.cl_ordered_statics
 
 
-let escape_res_name name allow_dirs =
+let escape_res_name name allowed =
 	ExtString.String.replace_chars (fun chr ->
 	ExtString.String.replace_chars (fun chr ->
 		if (chr >= 'a' && chr <= 'z') || (chr >= 'A' && chr <= 'Z') || (chr >= '0' && chr <= '9') || chr = '_' || chr = '.' then
 		if (chr >= 'a' && chr <= 'z') || (chr >= 'A' && chr <= 'Z') || (chr >= '0' && chr <= '9') || chr = '_' || chr = '.' then
 			Char.escaped chr
 			Char.escaped chr
-		else if chr = '/' && allow_dirs then
-			"/"
+		else if List.mem chr allowed then
+			Char.escaped chr
 		else
 		else
 			"-x" ^ (string_of_int (Char.code chr))) name
 			"-x" ^ (string_of_int (Char.code chr))) name
 
 
@@ -123,8 +122,13 @@ let fix_override com c f fd =
 					(* Flash generates type parameters with a single constraint as that constraint type, so we
 					(* Flash generates type parameters with a single constraint as that constraint type, so we
 					   have to detect this case and change the variable (issue #2712). *)
 					   have to detect this case and change the variable (issue #2712). *)
 					begin match follow v.v_type with
 					begin match follow v.v_type with
-						| TInst({cl_kind = KTypeParameter [tc]} as cp,_) when com.platform = Flash ->
-							if List.exists (fun tp -> tp.ttp_name = (snd cp.cl_path)) c.cl_params then raise (Unify_error [])
+						| TInst({cl_kind = KTypeParameter ttp} as cp,_) when com.platform = Flash ->
+							begin match get_constraints ttp with
+							| [tc] ->
+								if List.exists (fun tp -> tp.ttp_name = (snd cp.cl_path)) c.cl_params then raise (Unify_error [])
+							| _ ->
+								()
+							end
 						| _ ->
 						| _ ->
 							()
 							()
 					end;
 					end;
@@ -236,11 +240,16 @@ module Dump = struct
 		let buf,close = create_dumpfile [] ((dump_path com) :: (platform_name_macro com) :: fst path @ [snd path]) in
 		let buf,close = create_dumpfile [] ((dump_path com) :: (platform_name_macro com) :: fst path @ [snd path]) in
 		buf,close
 		buf,close
 
 
-	let dump_types com s_expr =
+	let dump_types com pretty =
 		let s_type = s_type (Type.print_context()) in
 		let s_type = s_type (Type.print_context()) in
+		let s_expr,s_type_param = if not pretty then
+			(Type.s_expr_ast (not (Common.defined com Define.DumpIgnoreVarIds)) "\t"),(Printer.s_type_param "")
+		else
+			(Type.s_expr_pretty false "\t" true),(s_type_param s_type)
+		in
 		let params tl = match tl with
 		let params tl = match tl with
 			| [] -> ""
 			| [] -> ""
-			| l -> Printf.sprintf "<%s>" (String.concat ", " (List.map Printer.s_type_param l))
+			| l -> Printf.sprintf "<%s>" (String.concat ", " (List.map s_type_param l))
 		in
 		in
 		List.iter (fun mt ->
 		List.iter (fun mt ->
 			let path = Type.t_path mt in
 			let path = Type.t_path mt in
@@ -372,11 +381,10 @@ module Dump = struct
 
 
 	let dump_types com =
 	let dump_types com =
 		match Common.defined_value_safe com Define.Dump with
 		match Common.defined_value_safe com Define.Dump with
-			| "pretty" -> dump_types com (Type.s_expr_pretty false "\t" true)
-			| "legacy" -> dump_types com Type.s_expr
+			| "pretty" -> dump_types com true
 			| "record" -> dump_record com
 			| "record" -> dump_record com
 			| "position" -> dump_position com
 			| "position" -> dump_position com
-			| _ -> dump_types com (Type.s_expr_ast (not (Common.defined com Define.DumpIgnoreVarIds)) "\t")
+			| _ -> dump_types com false 
 
 
 	let dump_dependencies ?(target_override=None) com =
 	let dump_dependencies ?(target_override=None) com =
 		let target_name = match target_override with
 		let target_name = match target_override with
@@ -389,7 +397,8 @@ module Dump = struct
 		let dep = Hashtbl.create 0 in
 		let dep = Hashtbl.create 0 in
 		List.iter (fun m ->
 		List.iter (fun m ->
 			print "%s:\n" (Path.UniqueKey.lazy_path m.m_extra.m_file);
 			print "%s:\n" (Path.UniqueKey.lazy_path m.m_extra.m_file);
-			PMap.iter (fun _ m2 ->
+			PMap.iter (fun _ (sign,mpath) ->
+				let m2 = com.module_lut#find mpath in
 				let file = Path.UniqueKey.lazy_path m2.m_extra.m_file in
 				let file = Path.UniqueKey.lazy_path m2.m_extra.m_file in
 				print "\t%s\n" file;
 				print "\t%s\n" file;
 				let l = try Hashtbl.find dep file with Not_found -> [] in
 				let l = try Hashtbl.find dep file with Not_found -> [] in
@@ -415,16 +424,10 @@ end
 *)
 *)
 let default_cast ?(vtmp="$t") com e texpr t p =
 let default_cast ?(vtmp="$t") com e texpr t p =
 	let api = com.basic in
 	let api = com.basic in
-	let mk_texpr = function
-		| TClassDecl c -> mk_anon (ref (Statics c))
-		| TEnumDecl e -> mk_anon (ref (EnumStatics e))
-		| TAbstractDecl a -> mk_anon (ref (AbstractStatics a))
-		| TTypeDecl _ -> die "" __LOC__
-	in
 	let vtmp = alloc_var VGenerated vtmp e.etype e.epos in
 	let vtmp = alloc_var VGenerated vtmp e.etype e.epos in
 	let var = mk (TVar (vtmp,Some e)) api.tvoid p in
 	let var = mk (TVar (vtmp,Some e)) api.tvoid p in
 	let vexpr = mk (TLocal vtmp) e.etype p in
 	let vexpr = mk (TLocal vtmp) e.etype p in
-	let texpr = mk (TTypeExpr texpr) (mk_texpr texpr) p in
+	let texpr = Texpr.Builder.make_typeexpr texpr p in
 	let std = (try List.find (fun t -> t_path t = ([],"Std")) com.types with Not_found -> die "" __LOC__) in
 	let std = (try List.find (fun t -> t_path t = ([],"Std")) com.types with Not_found -> die "" __LOC__) in
 	let fis = (try
 	let fis = (try
 			let c = (match std with TClassDecl c -> c | _ -> die "" __LOC__) in
 			let c = (match std with TClassDecl c -> c | _ -> die "" __LOC__) in
@@ -432,7 +435,7 @@ let default_cast ?(vtmp="$t") com e texpr t p =
 		with Not_found ->
 		with Not_found ->
 			die "" __LOC__
 			die "" __LOC__
 	) in
 	) in
-	let std = mk (TTypeExpr std) (mk_texpr std) p in
+	let std = Texpr.Builder.make_typeexpr std p in
 	let is = mk (TField (std,fis)) (tfun [t_dynamic;t_dynamic] api.tbool) p in
 	let is = mk (TField (std,fis)) (tfun [t_dynamic;t_dynamic] api.tbool) p in
 	let is = mk (TCall (is,[vexpr;texpr])) api.tbool p in
 	let is = mk (TCall (is,[vexpr;texpr])) api.tbool p in
 	let enull = Texpr.Builder.make_null vexpr.etype p in
 	let enull = Texpr.Builder.make_null vexpr.etype p in
@@ -478,10 +481,6 @@ let interpolate_code com code tl f_string f_expr p =
 			i := !i + String.length txt;
 			i := !i + String.length txt;
 			f_string txt;
 			f_string txt;
 			loop tl
 			loop tl
-		| Str.Delim a :: Str.Delim b :: tl when a = b ->
-			i := !i + 2;
-			f_string a;
-			loop tl
 		| Str.Delim "{" :: Str.Text n :: Str.Delim "}" :: tl ->
 		| Str.Delim "{" :: Str.Text n :: Str.Delim "}" :: tl ->
 			begin try
 			begin try
 				let expr = Array.get exprs (int_of_string n) in
 				let expr = Array.get exprs (int_of_string n) in
@@ -520,3 +519,4 @@ module ExtClass = struct
 		let e_assign = mk (TBinop(OpAssign,ef1,e)) e.etype p in
 		let e_assign = mk (TBinop(OpAssign,ef1,e)) e.etype p in
 		add_cl_init c e_assign
 		add_cl_init c e_assign
 end
 end
+	

+ 14 - 13
src/codegen/dotnet.ml

@@ -68,7 +68,7 @@ let cs_unops =
 let netname_to_hx name =
 let netname_to_hx name =
 	let len = String.length name in
 	let len = String.length name in
 	let chr = String.get name 0 in
 	let chr = String.get name 0 in
-	String.make 1 (Char.uppercase chr) ^ (String.sub name 1 (len-1))
+	String.make 1 (Char.uppercase_ascii chr) ^ (String.sub name 1 (len-1))
 
 
 (* -net-lib implementation *)
 (* -net-lib implementation *)
 
 
@@ -105,7 +105,7 @@ let escape_chars =
 
 
 let netcl_to_hx cl =
 let netcl_to_hx cl =
 	let cl = if String.length cl > 0 && String.get cl 0 >= 'a' && String.get cl 0 <= 'z' then
 	let cl = if String.length cl > 0 && String.get cl 0 >= 'a' && String.get cl 0 <= 'z' then
-			Char.escaped (Char.uppercase (String.get cl 0)) ^ (String.sub cl 1 (String.length cl - 1))
+			Char.escaped (Char.uppercase_ascii (String.get cl 0)) ^ (String.sub cl 1 (String.length cl - 1))
 		else
 		else
 			cl
 			cl
 	in
 	in
@@ -145,7 +145,7 @@ let mk_type_path ctx path params =
 			let nested = List.map (netcl_to_hx) nested in
 			let nested = List.map (netcl_to_hx) nested in
 			ns, Some (String.concat "_" nested ^ "_" ^ netcl_to_hx cl), nhd
 			ns, Some (String.concat "_" nested ^ "_" ^ netcl_to_hx cl), nhd
 	in
 	in
-	CTPath {
+	make_ptp_ct_null {
 		tpackage = fst (netpath_to_hx ctx.nstd (pack,[],""));
 		tpackage = fst (netpath_to_hx ctx.nstd (pack,[],""));
 		Ast.tname = name;
 		Ast.tname = name;
 		tparams = params;
 		tparams = params;
@@ -153,12 +153,13 @@ let mk_type_path ctx path params =
 	}
 	}
 
 
 let raw_type_path ctx path params =
 let raw_type_path ctx path params =
-	{
+	let tp = {
 		tpackage = fst path;
 		tpackage = fst path;
 		Ast.tname = snd path;
 		Ast.tname = snd path;
 		tparams = params;
 		tparams = params;
 		tsub = None;
 		tsub = None;
-	}
+	} in
+	make_ptp tp null_pos
 
 
 let rec convert_signature ctx p = function
 let rec convert_signature ctx p = function
 	| LVoid ->
 	| LVoid ->
@@ -577,7 +578,7 @@ let convert_ilprop ctx p prop is_explicit_impl =
 		cff_kind = kind;
 		cff_kind = kind;
 	}
 	}
 
 
-let get_type_path ctx ct = match ct with | CTPath p -> p | _ -> die "" __LOC__
+let get_type_path ctx ct = match ct with | CTPath ptp -> ptp | _ -> die "" __LOC__
 
 
 let is_explicit ctx ilcls i =
 let is_explicit ctx ilcls i =
 	let s = match i with
 	let s = match i with
@@ -754,12 +755,12 @@ let convert_ilclass ctx p ?(delegate=false) ilcls = match ilcls.csuper with
 		(match ilcls.csuper with
 		(match ilcls.csuper with
 			| Some { snorm = LClass ( (["System"],[],"Object"), [] ) } -> ()
 			| Some { snorm = LClass ( (["System"],[],"Object"), [] ) } -> ()
 			| Some ({ snorm = LClass ( (["System"],[],"ValueType"), [] ) } as s) ->
 			| Some ({ snorm = LClass ( (["System"],[],"ValueType"), [] ) } as s) ->
-				flags := HExtends (get_type_path ctx (convert_signature ctx p s.snorm),null_pos) :: !flags;
+				flags := HExtends (get_type_path ctx (convert_signature ctx p s.snorm)) :: !flags;
 				meta := (Meta.Struct,[],p) :: !meta
 				meta := (Meta.Struct,[],p) :: !meta
 			| Some { snorm = LClass ( (["haxe";"lang"],[],"HxObject"), [] ) } ->
 			| Some { snorm = LClass ( (["haxe";"lang"],[],"HxObject"), [] ) } ->
 				meta := (Meta.HxGen,[],p) :: !meta
 				meta := (Meta.HxGen,[],p) :: !meta
 			| Some s ->
 			| Some s ->
-				flags := HExtends (get_type_path ctx (convert_signature ctx p s.snorm),null_pos) :: !flags
+				flags := HExtends (get_type_path ctx (convert_signature ctx p s.snorm)) :: !flags
 			| _ -> ());
 			| _ -> ());
 
 
 			let has_explicit_ifaces = ref false in
 			let has_explicit_ifaces = ref false in
@@ -771,9 +772,9 @@ let convert_ilclass ctx p ?(delegate=false) ilcls = match ilcls.csuper with
 				| i ->
 				| i ->
 					if is_explicit ctx ilcls i then has_explicit_ifaces := true;
 					if is_explicit ctx ilcls i then has_explicit_ifaces := true;
 					flags := if !is_interface then
 					flags := if !is_interface then
-						HExtends (get_type_path ctx (convert_signature ctx p i),null_pos) :: !flags
+						HExtends (get_type_path ctx (convert_signature ctx p i)) :: !flags
 					else
 					else
-						HImplements (get_type_path ctx (convert_signature ctx p i),null_pos) :: !flags
+						HImplements (get_type_path ctx (convert_signature ctx p i)) :: !flags
 			) ilcls.cimplements;
 			) ilcls.cimplements;
 			(* this is needed because of explicit interfaces. see http://msdn.microsoft.com/en-us/library/aa288461(v=vs.71).aspx *)
 			(* this is needed because of explicit interfaces. see http://msdn.microsoft.com/en-us/library/aa288461(v=vs.71).aspx *)
 			(* explicit interfaces can't be mapped into Haxe in any way - since their fields can't be accessed directly, but they still implement that interface *)
 			(* explicit interfaces can't be mapped into Haxe in any way - since their fields can't be accessed directly, but they still implement that interface *)
@@ -784,9 +785,9 @@ let convert_ilclass ctx p ?(delegate=false) ilcls = match ilcls.csuper with
 			ignore (List.exists (function
 			ignore (List.exists (function
 			| { psig = { snorm = LMethod(_,ret,[v]) } } ->
 			| { psig = { snorm = LMethod(_,ret,[v]) } } ->
 				flags := if !is_interface then
 				flags := if !is_interface then
-					(HExtends( raw_type_path ctx ([],"ArrayAccess") [ TPType (convert_signature ctx p ret,null_pos) ],null_pos) :: !flags)
+					(HExtends( raw_type_path ctx ([],"ArrayAccess") [ TPType (convert_signature ctx p ret,null_pos) ]) :: !flags)
 				else
 				else
-					(HImplements( raw_type_path ctx ([],"ArrayAccess") [ TPType (convert_signature ctx p ret,null_pos) ],null_pos) :: !flags);
+					(HImplements( raw_type_path ctx ([],"ArrayAccess") [ TPType (convert_signature ctx p ret,null_pos) ]) :: !flags);
 				true
 				true
 			| _ -> false) ilcls.cprops);
 			| _ -> false) ilcls.cprops);
 
 
@@ -1112,7 +1113,7 @@ let normalize_ilcls ctx cls =
 	in
 	in
 	let refclsfields = List.fold_left fold_field [] refclsfields in
 	let refclsfields = List.fold_left fold_field [] refclsfields in
 
 
-	let rec fold (fields,methods,props) f = match !f with
+	let fold (fields,methods,props) f = match !f with
 		| IlField f,_,_,_ -> f :: fields,methods,props
 		| IlField f,_,_,_ -> f :: fields,methods,props
 		| IlMethod m,_,_,_ -> fields,m :: methods,props
 		| IlMethod m,_,_,_ -> fields,m :: methods,props
 		| IlProp p,_,_,_ -> fields,methods,p :: props
 		| IlProp p,_,_,_ -> fields,methods,p :: props

+ 14 - 7
src/codegen/gencommon/castDetect.ml

@@ -21,7 +21,6 @@ open Common
 open Ast
 open Ast
 open Globals
 open Globals
 open Type
 open Type
-open Codegen
 open Gencommon
 open Gencommon
 
 
 (* ******************************************* *)
 (* ******************************************* *)
@@ -241,7 +240,7 @@ let is_exactly_basic gen t1 t2 =
 		| _ ->
 		| _ ->
 			false
 			false
 
 
-let rec is_unsafe_cast gen to_t from_t =
+let is_unsafe_cast gen to_t from_t =
 	match (follow to_t, follow from_t) with
 	match (follow to_t, follow from_t) with
 		| TInst(cl_to, to_params), TInst(cl_from, from_params) ->
 		| TInst(cl_to, to_params), TInst(cl_from, from_params) ->
 			not (is_cl_related gen cl_from from_params cl_to to_params)
 			not (is_cl_related gen cl_from from_params cl_to to_params)
@@ -291,7 +290,7 @@ let do_unsafe_cast gen from_t to_t e	=
 			| _ -> raise Not_found
 			| _ -> raise Not_found
 	in
 	in
 	match gen.gfollow#run_f from_t, gen.gfollow#run_f to_t with
 	match gen.gfollow#run_f from_t, gen.gfollow#run_f to_t with
-	| TInst({ cl_kind = KTypeParameter tl },_), t2 when List.exists (fun t -> unifies t t2) tl ->
+	| TInst({ cl_kind = KTypeParameter ttp },_), t2 when List.exists (fun t -> unifies t t2) (get_constraints ttp) ->
 		mk_cast to_t (mk_cast t_dynamic e)
 		mk_cast to_t (mk_cast t_dynamic e)
 	| from_t, to_t when gen.gspecial_needs_cast to_t from_t ->
 	| from_t, to_t when gen.gspecial_needs_cast to_t from_t ->
 		mk_cast to_t e
 		mk_cast to_t e
@@ -419,7 +418,7 @@ let rec handle_cast gen e real_to_t real_from_t =
 				mk_cast true to_t e
 				mk_cast true to_t e
 		| _, TAnon(anon) -> (try
 		| _, TAnon(anon) -> (try
 			let p2 = match !(anon.a_status) with
 			let p2 = match !(anon.a_status) with
-			| Statics c -> TInst(c,List.map (fun _ -> t_dynamic) c.cl_params)
+			| ClassStatics c -> TInst(c,List.map (fun _ -> t_dynamic) c.cl_params)
 			| EnumStatics e -> TEnum(e, List.map (fun _ -> t_dynamic) e.e_params)
 			| EnumStatics e -> TEnum(e, List.map (fun _ -> t_dynamic) e.e_params)
 			| AbstractStatics a -> TAbstract(a, List.map (fun _ -> t_dynamic) a.a_params)
 			| AbstractStatics a -> TAbstract(a, List.map (fun _ -> t_dynamic) a.a_params)
 			| _ -> raise Not_found
 			| _ -> raise Not_found
@@ -657,7 +656,7 @@ let choose_ctor gen cl tparams etl maybe_empty_t p =
 		| _ ->
 		| _ ->
 			false
 			false
 	in
 	in
-	let rec check_cf cf =
+	let check_cf cf =
 		let t = apply_params sup.cl_params stl cf.cf_type in
 		let t = apply_params sup.cl_params stl cf.cf_type in
 		replace_mono t;
 		replace_mono t;
 		let args, _ = get_fun t in
 		let args, _ = get_fun t in
@@ -1271,8 +1270,16 @@ let configure gen ?(overloads_cast_to_base = false) maybe_empty_t calls_paramete
 				{ e with eexpr = TIf (handle (run econd) gen.gcon.basic.tbool econd.etype, (in_value := false; run (mk_block ethen)), Option.map (fun e -> in_value := false; run (mk_block e)) eelse) }
 				{ e with eexpr = TIf (handle (run econd) gen.gcon.basic.tbool econd.etype, (in_value := false; run (mk_block ethen)), Option.map (fun e -> in_value := false; run (mk_block e)) eelse) }
 			| TWhile (econd, e1, flag) ->
 			| TWhile (econd, e1, flag) ->
 				{ e with eexpr = TWhile (handle (run econd) gen.gcon.basic.tbool econd.etype, (in_value := false; run (mk_block e1)), flag) }
 				{ e with eexpr = TWhile (handle (run econd) gen.gcon.basic.tbool econd.etype, (in_value := false; run (mk_block e1)), flag) }
-			| TSwitch (cond, el_e_l, edef) ->
-				{ e with eexpr = TSwitch(run cond, List.map (fun (el,e) -> (List.map run el, (in_value := false; run (mk_block e)))) el_e_l, Option.map (fun e -> in_value := false; run (mk_block e)) edef) }
+			| TSwitch switch ->
+				let switch = { switch with
+					switch_subject = run switch.switch_subject;
+					switch_cases = List.map (fun case -> {
+						case_patterns = List.map run case.case_patterns;
+						case_expr = (in_value := false; run (mk_block case.case_expr))
+					}) switch.switch_cases;
+					switch_default = Option.map (fun e -> in_value := false; run (mk_block e)) switch.switch_default;
+				} in
+				{ e with eexpr = TSwitch switch }
 			| TFor (v,cond,e1) ->
 			| TFor (v,cond,e1) ->
 				{ e with eexpr = TFor(v, run cond, (in_value := false; run (mk_block e1))) }
 				{ e with eexpr = TFor(v, run cond, (in_value := false; run (mk_block e1))) }
 			| TTry (e, ve_l) ->
 			| TTry (e, ve_l) ->

+ 13 - 21
src/codegen/gencommon/closuresToClass.ml

@@ -19,7 +19,6 @@
 open Option
 open Option
 open Common
 open Common
 open Globals
 open Globals
-open Codegen
 open Texpr.Builder
 open Texpr.Builder
 open Ast
 open Ast
 open Type
 open Type
@@ -278,9 +277,8 @@ let traverse gen ?tparam_anon_decl ?tparam_anon_acc (handle_anon_func:texpr->tfu
 
 
 let rec get_type_params acc t =
 let rec get_type_params acc t =
 	match t with
 	match t with
-		| TInst(( { cl_kind = KTypeParameter constraints } as cl), []) ->
-			let params = List.fold_left get_type_params acc constraints in
-			List.filter (fun t -> not (List.memq t acc)) (cl :: params) @ acc;
+		| TInst(( { cl_kind = KTypeParameter _ } as cl), []) ->
+			if List.memq cl acc then acc else cl :: acc
 		| TFun (params,tret) ->
 		| TFun (params,tret) ->
 			List.fold_left get_type_params acc ( tret :: List.map (fun (_,_,t) -> t) params )
 			List.fold_left get_type_params acc ( tret :: List.map (fun (_,_,t) -> t) params )
 		| TDynamic None ->
 		| TDynamic None ->
@@ -291,10 +289,7 @@ let rec get_type_params acc t =
 				get_type_params acc ( Abstract.get_underlying_type a pl)
 				get_type_params acc ( Abstract.get_underlying_type a pl)
 		| TAnon a ->
 		| TAnon a ->
 			PMap.fold (fun cf acc ->
 			PMap.fold (fun cf acc ->
-				let params = List.map (fun tp -> match follow tp.ttp_type with
-					| TInst(c,_) -> c
-					| _ -> die "" __LOC__) cf.cf_params
-				in
+				let params = List.map (fun tp -> tp.ttp_class) cf.cf_params in
 				List.filter (fun t -> not (List.memq t params)) (get_type_params acc cf.cf_type)
 				List.filter (fun t -> not (List.memq t params)) (get_type_params acc cf.cf_type)
 			) a.a_fields acc
 			) a.a_fields acc
 		| TType(_, [])
 		| TType(_, [])
@@ -398,7 +393,7 @@ let configure gen ft =
 		in
 		in
 
 
 		(*let cltypes = List.map (fun cl -> (snd cl.cl_path, TInst(map_param cl, []) )) tparams in*)
 		(*let cltypes = List.map (fun cl -> (snd cl.cl_path, TInst(map_param cl, []) )) tparams in*)
-		let cltypes = List.map (fun cl -> mk_type_param (snd cl.cl_path) (TInst(cl, [])) None) tparams in
+		let cltypes = List.map (fun cl -> mk_type_param cl TPHType None None) tparams in
 
 
 		(* create a new class that extends abstract function class, with a ctor implementation that will setup all captured variables *)
 		(* create a new class that extends abstract function class, with a ctor implementation that will setup all captured variables *)
 		let cfield = match gen.gcurrent_classfield with
 		let cfield = match gen.gcurrent_classfield with
@@ -615,14 +610,10 @@ let configure gen ft =
 
 
 			let monos = List.map (fun t -> apply_params types (List.map (fun _ -> t_dynamic) types) t) monos in
 			let monos = List.map (fun t -> apply_params types (List.map (fun _ -> t_dynamic) types) t) monos in
 
 
-			let same_cl t1 t2 = match follow t1, follow t2 with
-				| TInst(c,_), TInst(c2,_) -> c == c2
-				| _ -> false
-			in
-			let passoc = List.map2 (fun tp m -> tp.ttp_type,m) types monos in
+			let passoc = List.map2 (fun tp m -> tp.ttp_class,m) types monos in
 			let cltparams = List.map (fun tp ->
 			let cltparams = List.map (fun tp ->
 				try
 				try
-					snd (List.find (fun (t2,_) -> same_cl tp.ttp_type t2) passoc)
+					snd (List.find (fun (t2,_) -> tp.ttp_class == t2) passoc)
 				with | Not_found -> tp.ttp_type) cls.cl_params
 				with | Not_found -> tp.ttp_type) cls.cl_params
 			in
 			in
 			{ e with eexpr = TNew(cls, cltparams, List.rev captured) }
 			{ e with eexpr = TNew(cls, cltparams, List.rev captured) }
@@ -1080,7 +1071,7 @@ struct
 			let cl = parent_func_class in
 			let cl = parent_func_class in
 			let pos = cl.cl_pos in
 			let pos = cl.cl_pos in
 
 
-			let rec mk_dyn_call arity api =
+			let mk_dyn_call arity api =
 				let zero = make_float gen.gcon.basic "0.0" pos in
 				let zero = make_float gen.gcon.basic "0.0" pos in
 				let rec loop i acc =
 				let rec loop i acc =
 					if i = 0 then
 					if i = 0 then
@@ -1099,7 +1090,10 @@ struct
 			let mk_invoke_switch i api =
 			let mk_invoke_switch i api =
 				let t = TFun (func_sig_i i, t_dynamic) in
 				let t = TFun (func_sig_i i, t_dynamic) in
 				(* case i: return this.invokeX_o(0, 0, 0, 0, 0, ... arg[0], args[1]....); *)
 				(* case i: return this.invokeX_o(0, 0, 0, 0, 0, ... arg[0], args[1]....); *)
-				[make_int gen.gcon.basic i pos], mk_return (mk (TCall(mk_this (iname i false) t, mk_dyn_call i api)) t_dynamic pos)
+				{
+					case_patterns = [make_int gen.gcon.basic i pos];
+					case_expr = mk_return (mk (TCall(mk_this (iname i false) t, mk_dyn_call i api)) t_dynamic pos)
+				}
 			in
 			in
 			let rec loop_cases api arity acc =
 			let rec loop_cases api arity acc =
 				if arity < 0 then
 				if arity < 0 then
@@ -1148,11 +1142,9 @@ struct
 						epos = pos;
 						epos = pos;
 					} in
 					} in
 
 
+					let switch = mk_switch switch_cond (loop_cases api !max_arity []) (Some(make_throw (mk_arg_exception "Too many arguments" pos) pos)) true in
 					{
 					{
-						eexpr = TSwitch(
-							switch_cond,
-							loop_cases api !max_arity [],
-							Some(make_throw (mk_arg_exception "Too many arguments" pos) pos));
+						eexpr = TSwitch switch;
 						etype = basic.tvoid;
 						etype = basic.tvoid;
 						epos = pos;
 						epos = pos;
 					}
 					}

+ 5 - 5
src/codegen/gencommon/dynamicFieldAccess.ml

@@ -33,7 +33,7 @@ open Gencommon
 
 
 	(TODO: should it be separated?)
 	(TODO: should it be separated?)
 	As a plus, the default implementation adds something that doesn't hurt anybody, it looks for
 	As a plus, the default implementation adds something that doesn't hurt anybody, it looks for
-	TAnon with Statics / EnumStatics field accesses and transforms them into real static calls.
+	TAnon with ClassStatics / EnumStatics field accesses and transforms them into real static calls.
 	This means it will take this
 	This means it will take this
 
 
 	var m = Math;
 	var m = Math;
@@ -58,8 +58,8 @@ let priority = solve_deps name [DAfter DynamicOperators.priority]
 *)
 *)
 let configure gen (is_dynamic:texpr->Type.tfield_access->bool) (change_expr:texpr->texpr->string->texpr option->bool->texpr) (call_expr:texpr->texpr->string->texpr list->texpr) =
 let configure gen (is_dynamic:texpr->Type.tfield_access->bool) (change_expr:texpr->texpr->string->texpr option->bool->texpr) (call_expr:texpr->texpr->string->texpr list->texpr) =
 	let is_nondynamic_tparam fexpr f = match follow fexpr.etype with
 	let is_nondynamic_tparam fexpr f = match follow fexpr.etype with
-		| TInst({ cl_kind = KTypeParameter(tl) }, _) ->
-			List.exists (fun t -> not (is_dynamic { fexpr with etype = t } f)) tl
+		| TInst({ cl_kind = KTypeParameter(ttp) }, _) ->
+			List.exists (fun t -> not (is_dynamic { fexpr with etype = t } f)) (get_constraints ttp)
 		| _ -> false
 		| _ -> false
 	in
 	in
 
 
@@ -68,8 +68,8 @@ let configure gen (is_dynamic:texpr->Type.tfield_access->bool) (change_expr:texp
 		(* class types *)
 		(* class types *)
 		| TField(fexpr, f) when is_nondynamic_tparam fexpr f ->
 		| TField(fexpr, f) when is_nondynamic_tparam fexpr f ->
 			(match follow fexpr.etype with
 			(match follow fexpr.etype with
-				| TInst( ({ cl_kind = KTypeParameter(tl) } as tp_cl), tp_tl) ->
-					let t = apply_params tp_cl.cl_params tp_tl (List.find (fun t -> not (is_dynamic { fexpr with etype = t } f)) tl) in
+				| TInst( ({ cl_kind = KTypeParameter(ttp) } as tp_cl), tp_tl) ->
+					let t = apply_params tp_cl.cl_params tp_tl (List.find (fun t -> not (is_dynamic { fexpr with etype = t } f)) (get_constraints ttp)) in
 					{ e with eexpr = TField(mk_cast t (run fexpr), f) }
 					{ e with eexpr = TField(mk_cast t (run fexpr), f) }
 				| _ -> Globals.die "" __LOC__)
 				| _ -> Globals.die "" __LOC__)
 
 

+ 0 - 1
src/codegen/gencommon/dynamicOperators.ml

@@ -19,7 +19,6 @@
 open Common
 open Common
 open Ast
 open Ast
 open Type
 open Type
-open Codegen
 open Texpr.Builder
 open Texpr.Builder
 open Gencommon
 open Gencommon
 
 

+ 2 - 3
src/codegen/gencommon/enumToClass.ml

@@ -20,7 +20,6 @@ open Common
 open Globals
 open Globals
 open Ast
 open Ast
 open Type
 open Type
-open Codegen
 open Texpr.Builder
 open Texpr.Builder
 open Gencommon
 open Gencommon
 
 
@@ -103,7 +102,7 @@ struct
 			| _ -> ());
 			| _ -> ());
 		let c_types =
 		let c_types =
 			if handle_type_params then
 			if handle_type_params then
-				List.map (fun tp -> {tp with ttp_type=TInst (map_param (get_cl_t tp.ttp_type), [])}) en.e_params
+				List.map clone_param en.e_params
 			else
 			else
 				[]
 				[]
 		in
 		in
@@ -121,7 +120,7 @@ struct
 				| TFun(params,ret) ->
 				| TFun(params,ret) ->
 					let dup_types =
 					let dup_types =
 						if handle_type_params then
 						if handle_type_params then
-							List.map (fun tp -> {tp with ttp_type = TInst (map_param (get_cl_t tp.ttp_type), [])}) en.e_params
+							List.map clone_param en.e_params
 						else
 						else
 							[]
 							[]
 					in
 					in

+ 0 - 1
src/codegen/gencommon/enumToClass2.ml

@@ -18,7 +18,6 @@
 *)
 *)
 open Common
 open Common
 open Ast
 open Ast
-open Codegen
 open Texpr.Builder
 open Texpr.Builder
 open Type
 open Type
 open Gencommon
 open Gencommon

+ 18 - 6
src/codegen/gencommon/expressionUnwrap.ml

@@ -170,8 +170,12 @@ let rec expr_stat_map fn (expr:texpr) =
 			{ expr with eexpr = TIf(fn cond, eif, eelse) }
 			{ expr with eexpr = TIf(fn cond, eif, eelse) }
 		| TWhile(cond, block, flag) ->
 		| TWhile(cond, block, flag) ->
 			{ expr with eexpr = TWhile(fn cond, block, flag) }
 			{ expr with eexpr = TWhile(fn cond, block, flag) }
-		| TSwitch(cond, el_block_l, default) ->
-			{ expr with eexpr = TSwitch( fn cond, List.map (fun (el,block) -> (List.map fn el, block)) el_block_l, default ) }
+		| TSwitch switch ->
+			let switch = { switch with
+				switch_subject = fn switch.switch_subject;
+				switch_cases = List.map (fun case -> {case with case_patterns = List.map fn case.case_patterns}) switch.switch_cases;
+			} in
+			{ expr with eexpr = TSwitch switch }
 		| TReturn(eopt) ->
 		| TReturn(eopt) ->
 			{ expr with eexpr = TReturn(Option.map fn eopt) }
 			{ expr with eexpr = TReturn(Option.map fn eopt) }
 		| TThrow (texpr) ->
 		| TThrow (texpr) ->
@@ -361,8 +365,12 @@ let rec apply_assign assign_fun right =
 	match right.eexpr with
 	match right.eexpr with
 		| TBlock el ->
 		| TBlock el ->
 			{ right with eexpr = TBlock(apply_assign_block assign_fun el) }
 			{ right with eexpr = TBlock(apply_assign_block assign_fun el) }
-		| TSwitch (cond, elblock_l, default) ->
-			{ right with eexpr = TSwitch(cond, List.map (fun (el,block) -> (el, mk_get_block assign_fun block)) elblock_l, Option.map (mk_get_block assign_fun) default) }
+		| TSwitch switch ->
+			let switch = { switch with
+				switch_cases = List.map (fun case -> {case with case_expr = mk_get_block assign_fun case.case_expr}) switch.switch_cases;
+				switch_default = Option.map (mk_get_block assign_fun) switch.switch_default;
+			} in
+			{ right with eexpr = TSwitch switch }
 		| TTry (block, catches) ->
 		| TTry (block, catches) ->
 			{ right with eexpr = TTry(mk_get_block assign_fun block, List.map (fun (v,block) -> (v,mk_get_block assign_fun block) ) catches) }
 			{ right with eexpr = TTry(mk_get_block assign_fun block, List.map (fun (v,block) -> (v,mk_get_block assign_fun block) ) catches) }
 		| TIf (cond,eif,eelse) ->
 		| TIf (cond,eif,eelse) ->
@@ -621,8 +629,12 @@ let configure gen =
 			{ e with eexpr = TBlock block }
 			{ e with eexpr = TBlock block }
 		| TTry (block, catches) ->
 		| TTry (block, catches) ->
 			{ e with eexpr = TTry(traverse (mk_block block), List.map (fun (v,block) -> (v, traverse (mk_block block))) catches) }
 			{ e with eexpr = TTry(traverse (mk_block block), List.map (fun (v,block) -> (v, traverse (mk_block block))) catches) }
-		| TSwitch (cond,el_e_l, default) ->
-			{ e with eexpr = TSwitch(cond, List.map (fun (el,e) -> (el, traverse (mk_block e))) el_e_l, Option.map (fun e -> traverse (mk_block e)) default) }
+		| TSwitch switch ->
+			let switch = { switch with
+				switch_cases = List.map (fun case -> {case with case_expr = traverse (mk_block case.case_expr)}) switch.switch_cases;
+				switch_default = Option.map (fun e -> traverse (mk_block e)) switch.switch_default;
+			} in
+			{ e with eexpr = TSwitch switch }
 		| TWhile (cond,block,flag) ->
 		| TWhile (cond,block,flag) ->
 			{e with eexpr = TWhile(cond,traverse (mk_block block), flag) }
 			{e with eexpr = TWhile(cond,traverse (mk_block block), flag) }
 		| TIf (cond, eif, eelse) ->
 		| TIf (cond, eif, eelse) ->

+ 1 - 1
src/codegen/gencommon/filterClosures.ml

@@ -28,7 +28,7 @@ open Gencommon
 	not via reflection and not to be called instantly
 	not via reflection and not to be called instantly
 
 
 	dependencies:
 	dependencies:
-		must run after DynamicFieldAccess, so any TAnon { Statics / EnumStatics } will be changed to the corresponding TTypeExpr
+		must run after DynamicFieldAccess, so any TAnon { ClassStatics / EnumStatics } will be changed to the corresponding TTypeExpr
 *)
 *)
 let name = "filter_closures"
 let name = "filter_closures"
 let priority = solve_deps name [DAfter DynamicFieldAccess.priority]
 let priority = solve_deps name [DAfter DynamicFieldAccess.priority]

+ 1 - 2
src/codegen/gencommon/fixOverrides.ml

@@ -19,7 +19,6 @@
 open Option
 open Option
 open Common
 open Common
 open Type
 open Type
-open Codegen
 open Gencommon
 open Gencommon
 
 
 (* ******************************************* *)
 (* ******************************************* *)
@@ -161,7 +160,7 @@ let run ~explicit_fn_name ~get_vmtype gen =
 			in
 			in
 			List.iter (fun (iface,itl) -> loop_iface iface itl) c.cl_implements;
 			List.iter (fun (iface,itl) -> loop_iface iface itl) c.cl_implements;
 			(* now go through all overrides, *)
 			(* now go through all overrides, *)
-			let rec check_f f =
+			let check_f f =
 				(* find the first declared field *)
 				(* find the first declared field *)
 				let is_overload = has_class_field_flag f CfOverload in
 				let is_overload = has_class_field_flag f CfOverload in
 				let decl = if is_overload then
 				let decl = if is_overload then

+ 14 - 12
src/codegen/gencommon/gencommon.ml

@@ -60,7 +60,6 @@ open Globals
 open Option
 open Option
 open Printf
 open Printf
 open ExtString
 open ExtString
-open Codegen
 open Overloads
 open Overloads
 
 
 (* ******************************************* *)
 (* ******************************************* *)
@@ -132,7 +131,7 @@ let path_of_md_def md_def =
 		| _ -> md_def.m_path
 		| _ -> md_def.m_path
 
 
 let debug_type t = (s_type (print_context())) t
 let debug_type t = (s_type (print_context())) t
-let debug_expr = s_expr debug_type
+let debug_expr = s_expr_ast true "" debug_type
 
 
 let debug_mode = ref false
 let debug_mode = ref false
 let trace s = if !debug_mode then print_endline s else ()
 let trace s = if !debug_mode then print_endline s else ()
@@ -147,7 +146,7 @@ let anon_class t =
 	match follow t with
 	match follow t with
 	| TAnon anon ->
 	| TAnon anon ->
 		(match !(anon.a_status) with
 		(match !(anon.a_status) with
-		| Statics cl -> Some (TClassDecl cl)
+		| ClassStatics cl -> Some (TClassDecl cl)
 		| EnumStatics e -> Some (TEnumDecl e)
 		| EnumStatics e -> Some (TEnumDecl e)
 		| AbstractStatics a -> Some (TAbstractDecl a)
 		| AbstractStatics a -> Some (TAbstractDecl a)
 		| _ -> None)
 		| _ -> None)
@@ -161,7 +160,7 @@ let anon_class t =
 	| TAnon anon ->
 	| TAnon anon ->
 		(match !(anon.a_status) with
 		(match !(anon.a_status) with
 			| EnumStatics e -> TEnumDecl e
 			| EnumStatics e -> TEnumDecl e
-			| Statics cl -> TClassDecl cl
+			| ClassStatics cl -> TClassDecl cl
 			| AbstractStatics a -> TAbstractDecl a
 			| AbstractStatics a -> TAbstractDecl a
 			| _ -> die "" __LOC__)
 			| _ -> die "" __LOC__)
 	| TLazy f -> t_to_md (lazy_type f)
 	| TLazy f -> t_to_md (lazy_type f)
@@ -627,11 +626,11 @@ let new_ctx con =
 		gadd_type = (fun md should_filter ->
 		gadd_type = (fun md should_filter ->
 			if should_filter then begin
 			if should_filter then begin
 				gen.gtypes_list <- md :: gen.gtypes_list;
 				gen.gtypes_list <- md :: gen.gtypes_list;
-				gen.gmodules <- { m_id = alloc_mid(); m_path = (t_path md); m_types = [md]; m_statics = None; m_extra = module_extra "" "" 0. MFake [] } :: gen.gmodules;
+				gen.gmodules <- { m_id = alloc_mid(); m_path = (t_path md); m_types = [md]; m_statics = None; m_extra = module_extra "" "" 0. MFake gen.gcon.compilation_step [] } :: gen.gmodules;
 				Hashtbl.add gen.gtypes (t_path md) md;
 				Hashtbl.add gen.gtypes (t_path md) md;
 			end else gen.gafter_filters_ended <- (fun () ->
 			end else gen.gafter_filters_ended <- (fun () ->
 				gen.gtypes_list <- md :: gen.gtypes_list;
 				gen.gtypes_list <- md :: gen.gtypes_list;
-				gen.gmodules <- { m_id = alloc_mid(); m_path = (t_path md); m_types = [md]; m_statics = None; m_extra = module_extra "" "" 0. MFake [] } :: gen.gmodules;
+				gen.gmodules <- { m_id = alloc_mid(); m_path = (t_path md); m_types = [md]; m_statics = None; m_extra = module_extra "" "" 0. MFake gen.gcon.compilation_step [] } :: gen.gmodules;
 				Hashtbl.add gen.gtypes (t_path md) md;
 				Hashtbl.add gen.gtypes (t_path md) md;
 			) :: gen.gafter_filters_ended;
 			) :: gen.gafter_filters_ended;
 		);
 		);
@@ -730,9 +729,9 @@ let run_filters_from gen t filters =
 		()
 		()
 
 
 let run_filters gen =
 let run_filters gen =
-	let last_error = gen.gcon.error in
+	let last_error = gen.gcon.error_ext in
 	let has_errors = ref false in
 	let has_errors = ref false in
-	gen.gcon.error <- (fun ?(depth=0) msg pos -> has_errors := true; last_error ~depth msg pos);
+	gen.gcon.error_ext <- (fun err -> has_errors := true; last_error err);
 	(* first of all, we have to make sure that the filters won't trigger a major Gc collection *)
 	(* first of all, we have to make sure that the filters won't trigger a major Gc collection *)
 	let t = Timer.timer ["gencommon_filters"] in
 	let t = Timer.timer ["gencommon_filters"] in
 	(if Common.defined gen.gcon Define.GencommonDebug then debug_mode := true else debug_mode := false);
 	(if Common.defined gen.gcon Define.GencommonDebug then debug_mode := true else debug_mode := false);
@@ -820,7 +819,7 @@ let run_filters gen =
 
 
 	reorder_modules gen;
 	reorder_modules gen;
 	t();
 	t();
-	if !has_errors then raise (Abort("Compilation aborted with errors",null_pos))
+	if !has_errors then abort "Compilation aborted with errors" null_pos
 
 
 (* ******************************************* *)
 (* ******************************************* *)
 (* basic generation module that source code compilation implementations can use *)
 (* basic generation module that source code compilation implementations can use *)
@@ -1138,11 +1137,14 @@ let mk_class_field ?(static = false) name t public pos kind params =
 (* this helper just duplicates the type parameter class, which is assumed that cl is. *)
 (* this helper just duplicates the type parameter class, which is assumed that cl is. *)
 (* This is so we can use class parameters on function parameters, without running the risk of name clash *)
 (* This is so we can use class parameters on function parameters, without running the risk of name clash *)
 (* between both *)
 (* between both *)
-let map_param cl =
+let clone_param ttp =
+	let cl = ttp.ttp_class in
 	let ret = mk_class cl.cl_module (fst cl.cl_path, snd cl.cl_path ^ "_c") cl.cl_pos null_pos in
 	let ret = mk_class cl.cl_module (fst cl.cl_path, snd cl.cl_path ^ "_c") cl.cl_pos null_pos in
 	ret.cl_implements <- cl.cl_implements;
 	ret.cl_implements <- cl.cl_implements;
 	ret.cl_kind <- cl.cl_kind;
 	ret.cl_kind <- cl.cl_kind;
-	ret
+	let ttp = mk_type_param ret ttp.ttp_host ttp.ttp_default ttp.ttp_constraints in
+	ret.cl_kind <- KTypeParameter ttp;
+	ttp
 
 
 let get_cl_t t =
 let get_cl_t t =
 	match follow t with | TInst (cl,_) -> cl | _ -> die "" __LOC__
 	match follow t with | TInst (cl,_) -> cl | _ -> die "" __LOC__
@@ -1275,7 +1277,7 @@ let rec field_access gen (t:t) (field:string) : (tfield_access) =
 				FNotFound)
 				FNotFound)
 		| TAnon anon ->
 		| TAnon anon ->
 			(try match !(anon.a_status) with
 			(try match !(anon.a_status) with
-				| Statics cl ->
+				| ClassStatics cl ->
 					let cf = PMap.find field cl.cl_statics in
 					let cf = PMap.find field cl.cl_statics in
 					FClassField(cl, List.map (fun _ -> t_dynamic) cl.cl_params, cl, cf, true, cf.cf_type, cf.cf_type)
 					FClassField(cl, List.map (fun _ -> t_dynamic) cl.cl_params, cl, cf, true, cf.cf_type, cf.cf_type)
 				| EnumStatics e ->
 				| EnumStatics e ->

+ 0 - 1
src/codegen/gencommon/initFunction.ml

@@ -18,7 +18,6 @@
 *)
 *)
 open Common
 open Common
 open Type
 open Type
-open Codegen
 open Texpr.Builder
 open Texpr.Builder
 open Gencommon
 open Gencommon
 
 

+ 9 - 11
src/codegen/gencommon/overloadingConstructor.ml

@@ -19,7 +19,6 @@
 open Option
 open Option
 open Common
 open Common
 open Type
 open Type
-open Codegen
 open Gencommon
 open Gencommon
 
 
 (* ******************************************* *)
 (* ******************************************* *)
@@ -114,16 +113,15 @@ let create_static_ctor com ~empty_ctor_expr cl ctor follow_type =
 	| false ->
 	| false ->
 		let static_ctor_name = make_static_ctor_name cl in
 		let static_ctor_name = make_static_ctor_name cl in
 		(* create the static constructor *)
 		(* create the static constructor *)
-		let ctor_types = List.map (fun tp -> {tp with ttp_type = TInst(map_param (get_cl_t tp.ttp_type), [])}) cl.cl_params in
+		let ctor_types = List.map clone_param cl.cl_params in
 		let ctor_type_params = extract_param_types ctor_types in
 		let ctor_type_params = extract_param_types ctor_types in
-		List.iter (function {ttp_type=TInst(c,[])} -> (
-			match c.cl_kind with
-			| KTypeParameter (hd :: tail) ->
-				let before = hd :: tail in
-				let after = List.map (apply_params cl.cl_params ctor_type_params) (before) in
-				c.cl_kind <- KTypeParameter(after)
-			| _ -> ())
-		| _ -> ()) ctor_types;
+		List.iter (fun ttp -> match get_constraints ttp with
+			| [] ->
+				()
+			| before ->
+				let after = List.map (apply_params cl.cl_params ctor_type_params) before in
+				ttp.ttp_constraints <- Some (lazy after)
+		) ctor_types;
 		let me = alloc_var "__hx_this" (TInst(cl, extract_param_types ctor_types)) in
 		let me = alloc_var "__hx_this" (TInst(cl, extract_param_types ctor_types)) in
 		add_var_flag me VCaptured;
 		add_var_flag me VCaptured;
 
 
@@ -237,7 +235,7 @@ let create_static_ctor com ~empty_ctor_expr cl ctor follow_type =
 
 
 (* makes constructors that only call super() for the 'ctor' argument *)
 (* makes constructors that only call super() for the 'ctor' argument *)
 let clone_ctors com ctor sup stl cl =
 let clone_ctors com ctor sup stl cl =
-	let rec clone cf =
+	let clone cf =
 		let ncf = mk_class_field "new" (apply_params sup.cl_params stl cf.cf_type) (has_class_field_flag cf CfPublic) cf.cf_pos cf.cf_kind cf.cf_params in
 		let ncf = mk_class_field "new" (apply_params sup.cl_params stl cf.cf_type) (has_class_field_flag cf CfPublic) cf.cf_pos cf.cf_kind cf.cf_params in
 		if Meta.has Meta.Protected cf.cf_meta then
 		if Meta.has Meta.Protected cf.cf_meta then
 			ncf.cf_meta <- (Meta.Protected,[],ncf.cf_pos) :: ncf.cf_meta;
 			ncf.cf_meta <- (Meta.Protected,[],ncf.cf_pos) :: ncf.cf_meta;

+ 18 - 16
src/codegen/gencommon/realTypeParams.ml

@@ -20,7 +20,6 @@ open Option
 open Common
 open Common
 open Ast
 open Ast
 open Type
 open Type
-open Codegen
 open Texpr.Builder
 open Texpr.Builder
 open Gencommon
 open Gencommon
 
 
@@ -91,7 +90,7 @@ let rec has_type_params t =
 			List.exists (fun (n,o,t) -> has_type_params t) args || has_type_params ret
 			List.exists (fun (n,o,t) -> has_type_params t) args || has_type_params ret
 		| _ -> false
 		| _ -> false
 
 
-let rec follow_all_md md =
+let follow_all_md md =
 	let t = match md with
 	let t = match md with
 		| TClassDecl { cl_kind = KAbstractImpl a } ->
 		| TClassDecl { cl_kind = KAbstractImpl a } ->
 			TAbstract(a, extract_param_types a.a_params)
 			TAbstract(a, extract_param_types a.a_params)
@@ -309,10 +308,9 @@ let set_hxgeneric gen md =
 		if not ret then begin
 		if not ret then begin
 			match md with
 			match md with
 			| TClassDecl c ->
 			| TClassDecl c ->
-				let set_hxgeneric tp = match follow tp.ttp_type with
-					| TInst(c,_) ->
-						c.cl_meta <- (Meta.NativeGeneric, [], c.cl_pos) :: c.cl_meta
-					| _ -> ()
+				let set_hxgeneric tp =
+					let c = tp.ttp_class in
+					c.cl_meta <- (Meta.NativeGeneric, [], c.cl_pos) :: c.cl_meta
 				in
 				in
 				List.iter set_hxgeneric c.cl_params;
 				List.iter set_hxgeneric c.cl_params;
 				let rec handle_field cf =
 				let rec handle_field cf =
@@ -366,7 +364,7 @@ module RealTypeParamsModf =
 struct
 struct
 
 
 	let set_only_hxgeneric gen =
 	let set_only_hxgeneric gen =
-		let rec run md =
+		let run md =
 			match md with
 			match md with
 				| TTypeDecl _ | TAbstractDecl _ -> md
 				| TTypeDecl _ | TAbstractDecl _ -> md
 				| _ -> ignore (set_hxgeneric gen md); md
 				| _ -> ignore (set_hxgeneric gen md); md
@@ -401,7 +399,7 @@ struct
 
 
 		let rec loop curcls params level reverse_params =
 		let rec loop curcls params level reverse_params =
 			if (level <> 0 || (has_class_flag curcls CInterface) || (has_class_flag curcls CAbstract) ) && params <> [] && is_hxgeneric (TClassDecl curcls) then begin
 			if (level <> 0 || (has_class_flag curcls CInterface) || (has_class_flag curcls CAbstract) ) && params <> [] && is_hxgeneric (TClassDecl curcls) then begin
-				let cparams = List.map (fun tp -> {tp with ttp_type=TInst (map_param (get_cl_t tp.ttp_type), [])}) curcls.cl_params in
+				let cparams = List.map clone_param curcls.cl_params in
 				let name = get_cast_name curcls in
 				let name = get_cast_name curcls in
 				if not (PMap.mem name cl.cl_fields) then begin
 				if not (PMap.mem name cl.cl_fields) then begin
 					let reverse_params = List.map (apply_params curcls.cl_params params) reverse_params in
 					let reverse_params = List.map (apply_params curcls.cl_params params) reverse_params in
@@ -460,7 +458,7 @@ struct
 	let create_cast_cfield gen cl name =
 	let create_cast_cfield gen cl name =
 		reset_temps();
 		reset_temps();
 		let basic = gen.gcon.basic in
 		let basic = gen.gcon.basic in
-		let cparams = List.map (fun tp -> {tp with ttp_type = TInst (map_param (get_cl_t tp.ttp_type), [])}) cl.cl_params in
+		let cparams = List.map clone_param cl.cl_params in
 		let cfield = mk_class_field name (TFun([], t_dynamic)) false cl.cl_pos (Method MethNormal) cparams in
 		let cfield = mk_class_field name (TFun([], t_dynamic)) false cl.cl_pos (Method MethNormal) cparams in
 		let params = extract_param_types cparams in
 		let params = extract_param_types cparams in
 
 
@@ -522,7 +520,10 @@ struct
 						t_cf
 						t_cf
 						pos
 						pos
 				in
 				in
-				[make_string gen.gcon.basic cf.cf_name pos], expr
+				{
+					case_patterns = [make_string gen.gcon.basic cf.cf_name pos];
+					case_expr = expr;
+				}
 			) fields
 			) fields
 		in
 		in
 
 
@@ -567,10 +568,11 @@ struct
 						(
 						(
 							(* default: Reflect.setField(new_me, field, Reflect.field(this, field)) *)
 							(* default: Reflect.setField(new_me, field, Reflect.field(this, field)) *)
 							let edef = gen.gtools.r_set_field basic.tvoid local_new_me local_field (gen.gtools.r_field false basic.tvoid this local_field) in
 							let edef = gen.gtools.r_set_field basic.tvoid local_new_me local_field (gen.gtools.r_field false basic.tvoid this local_field) in
-							if fields <> [] then
+							if fields <> [] then begin
 								(* switch(field) { ... } *)
 								(* switch(field) { ... } *)
-								mk (TSwitch (local_field, fields_to_cases fields, Some edef)) basic.tvoid pos
-							else
+								let switch = mk_switch local_field (fields_to_cases fields) (Some edef) true in
+								mk (TSwitch switch) basic.tvoid pos
+							end else
 								edef;
 								edef;
 						)
 						)
 					]) basic.tvoid pos,
 					]) basic.tvoid pos,
@@ -587,7 +589,7 @@ struct
 	let create_static_cast_cf gen iface cf =
 	let create_static_cast_cf gen iface cf =
 		let p = iface.cl_pos in
 		let p = iface.cl_pos in
 		let basic = gen.gcon.basic in
 		let basic = gen.gcon.basic in
-		let cparams = List.map (fun tp -> {tp with ttp_name = "To_" ^ tp.ttp_name;ttp_type = TInst (map_param (get_cl_t tp.ttp_type), [])}) cf.cf_params in
+		let cparams = List.map clone_param cf.cf_params in
 		let me_type = TInst(iface,[]) in
 		let me_type = TInst(iface,[]) in
 		let cfield = mk_class_field ~static:true "__hx_cast" (TFun(["me",false,me_type], t_dynamic)) false iface.cl_pos (Method MethNormal) (cparams) in
 		let cfield = mk_class_field ~static:true "__hx_cast" (TFun(["me",false,me_type], t_dynamic)) false iface.cl_pos (Method MethNormal) (cparams) in
 		let params = extract_param_types cparams in
 		let params = extract_param_types cparams in
@@ -634,7 +636,7 @@ struct
 		let implement_stub_cast cthis iface tl =
 		let implement_stub_cast cthis iface tl =
 			let name = get_cast_name iface in
 			let name = get_cast_name iface in
 			if not (PMap.mem name cthis.cl_fields) then begin
 			if not (PMap.mem name cthis.cl_fields) then begin
-				let cparams = List.map (fun tp -> {tp with ttp_name = "To_" ^ tp.ttp_name;ttp_type = TInst(map_param (get_cl_t tp.ttp_type), [])}) iface.cl_params in
+				let cparams = List.map clone_param iface.cl_params in
 				let field = mk_class_field name (TFun([],t_dynamic)) false iface.cl_pos (Method MethNormal) cparams in
 				let field = mk_class_field name (TFun([],t_dynamic)) false iface.cl_pos (Method MethNormal) cparams in
 				let this = { eexpr = TConst TThis; etype = TInst(cthis, extract_param_types cthis.cl_params); epos = cthis.cl_pos } in
 				let this = { eexpr = TConst TThis; etype = TInst(cthis, extract_param_types cthis.cl_params); epos = cthis.cl_pos } in
 				field.cf_expr <- Some {
 				field.cf_expr <- Some {
@@ -651,7 +653,7 @@ struct
 			end
 			end
 		in
 		in
 
 
-		let rec run md =
+		let run md =
 			match md with
 			match md with
 				| TClassDecl ({ cl_params = [] } as cl) ->
 				| TClassDecl ({ cl_params = [] } as cl) ->
 					(* see if we're implementing any generic interface *)
 					(* see if we're implementing any generic interface *)

+ 32 - 26
src/codegen/gencommon/reflectionCFs.ml

@@ -20,7 +20,6 @@ open Option
 open Common
 open Common
 open Ast
 open Ast
 open Type
 open Type
-open Codegen
 open Texpr.Builder
 open Texpr.Builder
 open Gencommon
 open Gencommon
 open ClosuresToClass
 open ClosuresToClass
@@ -1000,11 +999,14 @@ let implement_get_set ctx cl =
 			(if fields <> [] then has_fields := true);
 			(if fields <> [] then has_fields := true);
 			let cases = List.map (fun (names, cf) ->
 			let cases = List.map (fun (names, cf) ->
 				(if names = [] then Globals.die "" __LOC__);
 				(if names = [] then Globals.die "" __LOC__);
-				(List.map (switch_case ctx pos) names, do_field cf cf.cf_type)
+				{
+					case_patterns = List.map (switch_case ctx pos) names;
+					case_expr = do_field cf cf.cf_type;
+				}
 			) fields in
 			) fields in
 			let default = Some(do_default()) in
 			let default = Some(do_default()) in
-
-			mk_block { eexpr = TSwitch(local_switch_var, cases, default); etype = basic.tvoid; epos = pos }
+			let switch = mk_switch local_switch_var cases default true in
+			mk_block { eexpr = TSwitch switch; etype = basic.tvoid; epos = pos }
 		in
 		in
 
 
 		let is_override = match cl.cl_super with
 		let is_override = match cl.cl_super with
@@ -1177,26 +1179,27 @@ let implement_invokeField ctx slow_invoke cl =
 				let t = apply_params cf.cf_params (List.map (fun _ -> t_dynamic) cf.cf_params) cf.cf_type in
 				let t = apply_params cf.cf_params (List.map (fun _ -> t_dynamic) cf.cf_params) cf.cf_type in
 				mk_this_call_raw cf.cf_name t params
 				mk_this_call_raw cf.cf_name t params
 			in
 			in
-			(cases,
-				mk_return (
-					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 }) }
+			{
+				case_patterns = cases;
+				case_expr =	mk_return (
+						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
+								mk (TIf (condition, ret, Some (make_null ret.etype pos))) ret.etype pos
 							else
 							else
 								ret
 								ret
-						in
-						incr i;
-						if optional then
-							let condition = binop OpGt dyn_arg_length idx ctx.rcf_gen.gcon.basic.tbool pos in
-							mk (TIf (condition, ret, Some (make_null ret.etype pos))) ret.etype pos
-						else
-							ret
-					) (fst (get_fun (cf.cf_type))))
-				)
-			)
+						) (fst (get_fun (cf.cf_type))))
+					)
+			}
 		in
 		in
 
 
 		let cfs = List.filter (fun (_,cf) -> match cf.cf_kind with
 		let cfs = List.filter (fun (_,cf) -> match cf.cf_kind with
@@ -1209,7 +1212,10 @@ let implement_invokeField ctx slow_invoke cl =
 			| [] -> cases
 			| [] -> cases
 			| _ ->
 			| _ ->
 				let ncases = List.map (fun cf -> switch_case ctx pos cf.cf_name) old in
 				let ncases = List.map (fun cf -> switch_case ctx pos cf.cf_name) old in
-				( ncases, mk_return (slow_invoke this (mk_local (fst (List.hd field_args)) pos) (mk_local dynamic_arg pos)) ) :: cases
+				{
+					case_patterns = ncases;
+					case_expr = mk_return (slow_invoke this (mk_local (fst (List.hd field_args)) pos) (mk_local dynamic_arg pos))
+				} :: cases
 		in
 		in
 
 
 		let default = if !is_override then
 		let default = if !is_override then
@@ -1235,9 +1241,9 @@ let implement_invokeField ctx slow_invoke cl =
 				epos = pos
 				epos = pos
 			} )
 			} )
 		in
 		in
-
+		let switch = mk_switch (mk_local switch_var pos) cases (Some default) true in
 		{
 		{
-			eexpr = TSwitch(mk_local switch_var pos, cases, Some default);
+			eexpr = TSwitch switch;
 			etype = basic.tvoid;
 			etype = basic.tvoid;
 			epos = pos;
 			epos = pos;
 		}
 		}
@@ -1483,7 +1489,7 @@ struct
 	let priority = min_dep +. 10.
 	let priority = min_dep +. 10.
 
 
 	let configure gen baseclass baseinterface basedynamic =
 	let configure gen baseclass baseinterface basedynamic =
-		let rec run md =
+		let run md =
 			if is_hxgen md then
 			if is_hxgen md then
 				match md with
 				match md with
 				| TClassDecl cl when (has_class_flag cl CInterface) && cl.cl_path <> baseclass.cl_path && cl.cl_path <> baseinterface.cl_path && cl.cl_path <> basedynamic.cl_path ->
 				| TClassDecl cl when (has_class_flag cl CInterface) && cl.cl_path <> baseclass.cl_path && cl.cl_path <> baseinterface.cl_path && cl.cl_path <> basedynamic.cl_path ->

+ 4 - 10
src/codegen/gencommon/renameTypeParameters.ml

@@ -41,22 +41,16 @@ let run types =
 		end else found_types := PMap.add name true !found_types
 		end else found_types := PMap.add name true !found_types
 	in
 	in
 
 
-	let get_cls t =
-		match follow t with
-		| TInst(cl,_) -> cl
-		| _ -> Globals.die "" __LOC__
-	in
-
 	let iter_types tp =
 	let iter_types tp =
-		let cls = get_cls tp.ttp_type in
+		let cls = tp.ttp_class in
 		let orig = cls.cl_path in
 		let orig = cls.cl_path in
 		check_type (snd orig) (fun name -> cls.cl_path <- (fst orig, name))
 		check_type (snd orig) (fun name -> cls.cl_path <- (fst orig, name))
 	in
 	in
 
 
 	let save_params save params =
 	let save_params save params =
 		List.fold_left (fun save tp ->
 		List.fold_left (fun save tp ->
-			let cls = get_cls tp.ttp_type in
-			(cls.cl_path,tp.ttp_type) :: save) save params
+			let cls = tp.ttp_class in
+			(cls.cl_path,tp.ttp_class) :: save) save params
 	in
 	in
 
 
 	List.iter (function
 	List.iter (function
@@ -82,7 +76,7 @@ let run types =
 				cl.cl_restore <- (fun () ->
 				cl.cl_restore <- (fun () ->
 					res();
 					res();
 					List.iter (fun (path,t) ->
 					List.iter (fun (path,t) ->
-						let cls = get_cls t in
+						let cls = t in
 						cls.cl_path <- path) save
 						cls.cl_path <- path) save
 				);
 				);
 			end
 			end

+ 15 - 10
src/codegen/gencommon/switchToIf.ml

@@ -18,7 +18,6 @@
 *)
 *)
 open Common
 open Common
 open Type
 open Type
-open Codegen
 open Gencommon
 open Gencommon
 
 
 (* ******************************************* *)
 (* ******************************************* *)
@@ -42,7 +41,7 @@ let configure gen (should_convert:texpr->bool) =
 	let basic = gen.gcon.basic in
 	let basic = gen.gcon.basic in
 	let rec run e =
 	let rec run e =
 		match e.eexpr with
 		match e.eexpr with
-		| TSwitch (cond, cases, default) when should_convert e ->
+		| TSwitch ({switch_subject = cond;switch_cases = cases;switch_default = default} as switch) when should_convert e ->
 			let cond_etype, should_cache =
 			let cond_etype, should_cache =
 				match gen.gfollow#run_f cond.etype with
 				match gen.gfollow#run_f cond.etype with
 				| TAbstract ({ a_path = [], "Null" }, [t]) ->
 				| TAbstract ({ a_path = [], "Null" }, [t]) ->
@@ -56,8 +55,13 @@ let configure gen (should_convert:texpr->bool) =
 					cond.etype, false
 					cond.etype, false
 			in
 			in
 
 
-			if should_cache && not (should_convert { e with eexpr = TSwitch ({ cond with etype = cond_etype }, cases, default) }) then begin
-				{ e with eexpr = TSwitch (mk_cast cond_etype (run cond), List.map (fun (cs,e) -> (List.map run cs, run e)) cases, Option.map run default) }
+			if should_cache && not (should_convert { e with eexpr = TSwitch {switch with switch_subject = { cond with etype = cond_etype }}}) then begin
+				let switch = { switch with
+					switch_subject = mk_cast cond_etype (run cond);
+					switch_cases = List.map (fun case -> {case_patterns = List.map run case.case_patterns;case_expr = run case.case_expr}) cases;
+					switch_default = Option.map run default;
+				} in
+				{ e with eexpr = TSwitch switch }
 			end else begin
 			end else begin
 				let local, fst_block =
 				let local, fst_block =
 					match cond.eexpr, should_cache with
 					match cond.eexpr, should_cache with
@@ -96,9 +100,9 @@ let configure gen (should_convert:texpr->bool) =
 
 
 				let rec loop cases =
 				let rec loop cases =
 					match cases with
 					match cases with
-					| (conds, e) :: [] ->
+					| {case_patterns = conds;case_expr = e} :: [] ->
 						mk (TIf (mk_many_cond conds, run e, Option.map run default)) e.etype e.epos
 						mk (TIf (mk_many_cond conds, run e, Option.map run default)) e.etype e.epos
-					| (conds, e) :: tl ->
+					| {case_patterns = conds;case_expr = e} :: tl ->
 						mk (TIf (mk_many_cond conds, run e, Some (loop tl))) e.etype e.epos
 						mk (TIf (mk_many_cond conds, run e, Some (loop tl))) e.etype e.epos
 					| [] ->
 					| [] ->
 						match default with
 						match default with
@@ -120,7 +124,7 @@ let configure gen (should_convert:texpr->bool) =
 			`switch e { case MyEnum.A: ...; case MyEnum.B: ...; }`, which is supported natively
 			`switch e { case MyEnum.A: ...; case MyEnum.B: ...; }`, which is supported natively
 			by some target languages like Java and C#.
 			by some target languages like Java and C#.
 		*)
 		*)
-		| TSwitch (cond, cases, default) ->
+		| TSwitch ({switch_subject = cond;switch_cases = cases;switch_default = default} as switch)  ->
 			begin
 			begin
 				try
 				try
 					match (simplify_expr cond).eexpr with
 					match (simplify_expr cond).eexpr with
@@ -138,7 +142,7 @@ let configure gen (should_convert:texpr->bool) =
 						PMap.iter (fun _ ef -> Hashtbl.add fields ef.ef_index ef) real_enum.e_constrs;
 						PMap.iter (fun _ ef -> Hashtbl.add fields ef.ef_index ef) real_enum.e_constrs;
 
 
 						let enum_expr = Texpr.Builder.make_typeexpr (TEnumDecl real_enum) e.epos in
 						let enum_expr = Texpr.Builder.make_typeexpr (TEnumDecl real_enum) e.epos in
-						let cases = List.map (fun (patterns, body) ->
+						let cases = List.map (fun {case_patterns = patterns; case_expr = body} ->
 							let patterns = List.map (fun e ->
 							let patterns = List.map (fun e ->
 								match e.eexpr with
 								match e.eexpr with
 								| TConst (TInt i) ->
 								| TConst (TInt i) ->
@@ -148,9 +152,10 @@ let configure gen (should_convert:texpr->bool) =
 									raise Not_found
 									raise Not_found
 							) patterns in
 							) patterns in
 							let body = run body in
 							let body = run body in
-							patterns, body
+							{ case_patterns = patterns;case_expr = body}
 						) cases in
 						) cases in
-						{ e with eexpr = TSwitch (enum, cases, Option.map run default) }
+						let switch = mk_switch enum cases (Option.map run default) switch.switch_exhaustive in
+						{ e with eexpr = TSwitch switch }
 					| _ ->
 					| _ ->
 						raise Not_found
 						raise Not_found
 				with Not_found ->
 				with Not_found ->

+ 6 - 2
src/codegen/gencommon/unnecessaryCastsRemoval.ml

@@ -40,8 +40,12 @@ let rec traverse e =
 		{ e with eexpr = TBlock bl }
 		{ e with eexpr = TBlock bl }
 	| TTry (block, catches) ->
 	| TTry (block, catches) ->
 		{ e with eexpr = TTry(traverse (mk_block block), List.map (fun (v,block) -> (v, traverse (mk_block block))) catches) }
 		{ e with eexpr = TTry(traverse (mk_block block), List.map (fun (v,block) -> (v, traverse (mk_block block))) catches) }
-	| TSwitch (cond,el_e_l, default) ->
-		{ e with eexpr = TSwitch(cond, List.map (fun (el,e) -> (el, traverse (mk_block e))) el_e_l, Option.map (fun e -> traverse (mk_block e)) default) }
+	| TSwitch switch ->
+		let switch = { switch with
+			switch_cases = List.map (fun case -> { case with case_expr = traverse (mk_block e)}) switch.switch_cases;
+			switch_default = Option.map (fun e -> traverse (mk_block e)) switch.switch_default;
+		} in
+		{ e with eexpr = TSwitch switch }
 	| TWhile (cond,block,flag) ->
 	| TWhile (cond,block,flag) ->
 		{e with eexpr = TWhile(cond,traverse (mk_block block), flag) }
 		{e with eexpr = TWhile(cond,traverse (mk_block block), flag) }
 	| TIf (cond, eif, eelse) ->
 	| TIf (cond, eif, eelse) ->

+ 16 - 9
src/codegen/gencommon/unreachableCodeEliminationSynf.ml

@@ -16,7 +16,6 @@
 	along with this program; if not, write to the Free Software
 	along with this program; if not, write to the Free Software
 	Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 	Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 *)
 *)
-open Common
 open Ast
 open Ast
 open Type
 open Type
 open Gencommon
 open Gencommon
@@ -178,17 +177,25 @@ let init gen java_mode =
 					has_break := last_has_break;
 					has_break := last_has_break;
 					return_loop { expr with eexpr = TWhile(cond,block,flag) } Normal
 					return_loop { expr with eexpr = TWhile(cond,block,flag) } Normal
 				end
 				end
-			| TSwitch(cond, el_e_l, None) ->
-				{ expr with eexpr = TSwitch(cond, List.map (fun (el, e) -> (el, handle_case (process_expr e))) el_e_l, None) }, Normal
-			| TSwitch(cond, el_e_l, Some def) ->
+			| TSwitch ({switch_default = None} as switch) ->
+				let switch = { switch with
+					switch_cases = List.map (fun case -> {case with case_expr = handle_case (process_expr case.case_expr)}) switch.switch_cases;
+					switch_default = None;
+				} in
+				{ expr with eexpr = TSwitch switch }, Normal
+			| TSwitch ({switch_default = Some def} as switch) ->
 				let def, k = process_expr def in
 				let def, k = process_expr def in
 				let def = handle_case (def, k) in
 				let def = handle_case (def, k) in
 				let k = ref k in
 				let k = ref k in
-				let ret = { expr with eexpr = TSwitch(cond, List.map (fun (el, e) ->
-					let e, ek = process_expr e in
-					k := aggregate_kind !k ek;
-					(el, handle_case (e, ek))
-				) el_e_l, Some def) } in
+				let switch = { switch with
+					switch_cases = List.map (fun case ->
+						let e, ek = process_expr case.case_expr in
+						k := aggregate_kind !k ek;
+						{case with case_expr = handle_case (e, ek)}
+					) switch.switch_cases;
+					switch_default = Some def;
+				} in
+				let ret = { expr with eexpr = TSwitch switch } in
 				ret, !k
 				ret, !k
 			| TTry (e, catches) ->
 			| TTry (e, catches) ->
 				let e, k = process_expr e in
 				let e, k = process_expr e in

+ 37 - 35
src/codegen/java.ml

@@ -46,7 +46,7 @@ let is_haxe_keyword = function
 let jname_to_hx name =
 let jname_to_hx name =
 	let name =
 	let name =
 		if name <> "" && (String.get name 0 < 'A' || String.get name 0 > 'Z') then
 		if name <> "" && (String.get name 0 < 'A' || String.get name 0 > 'Z') then
-			Char.escaped (Char.uppercase (String.get name 0)) ^ String.sub name 1 (String.length name - 1)
+			Char.escaped (Char.uppercase_ascii (String.get name 0)) ^ String.sub name 1 (String.length name - 1)
 		else
 		else
 			name
 			name
 	in
 	in
@@ -81,7 +81,7 @@ let lookup_jclass com path =
 		| Some p -> Some p
 		| Some p -> Some p
 	) com.native_libs.java_libs None
 	) com.native_libs.java_libs None
 
 
-let mk_type_path ctx path params =
+let mk_type_path ctx path params p =
 	let name, sub = try
 	let name, sub = try
 		let p, _ = String.split (snd path) "$" in
 		let p, _ = String.split (snd path) "$" in
 		jname_to_hx p, Some (jname_to_hx (snd path))
 		jname_to_hx p, Some (jname_to_hx (snd path))
@@ -104,31 +104,31 @@ let mk_type_path ctx path params =
 		| _ ->
 		| _ ->
 			pack, sub, name
 			pack, sub, name
 	in
 	in
-	CTPath {
+	make_ptp_ct {
 		tpackage = pack;
 		tpackage = pack;
 		tname = name;
 		tname = name;
 		tparams = params;
 		tparams = params;
 		tsub = sub;
 		tsub = sub;
-	}
+	} p
 
 
 let has_tparam name params = List.exists(fun (n,_,_) -> n = name) params
 let has_tparam name params = List.exists(fun (n,_,_) -> n = name) params
 
 
 let rec convert_arg ctx p arg =
 let rec convert_arg ctx p arg =
 	match arg with
 	match arg with
-	| TAny | TType (WSuper, _) -> TPType (mk_type_path ctx ([], "Dynamic") [],null_pos)
+	| TAny | TType (WSuper, _) -> TPType (mk_type_path ctx ([], "Dynamic") [] p,null_pos)
 	| TType (_, jsig) -> TPType (convert_signature ctx p jsig,null_pos)
 	| TType (_, jsig) -> TPType (convert_signature ctx p jsig,null_pos)
 
 
 and convert_signature ctx p jsig =
 and convert_signature ctx p jsig =
 	match jsig with
 	match jsig with
-	| TByte -> mk_type_path ctx (["java"; "types"], "Int8") []
-	| TChar -> mk_type_path ctx (["java"; "types"], "Char16") []
-	| TDouble -> mk_type_path ctx ([], "Float") []
-	| TFloat -> mk_type_path ctx ([], "Single") []
-	| TInt -> mk_type_path ctx ([], "Int") []
-	| TLong -> mk_type_path ctx (["haxe"], "Int64") []
-	| TShort -> mk_type_path ctx (["java"; "types"], "Int16") []
-	| TBool -> mk_type_path ctx ([], "Bool") []
-	| TObject ( (["haxe";"root"], name), args ) -> mk_type_path ctx ([], name) (List.map (convert_arg ctx p) args)
+	| TByte -> mk_type_path ctx (["java"; "types"], "Int8") [] p
+	| TChar -> mk_type_path ctx (["java"; "types"], "Char16") [] p
+	| TDouble -> mk_type_path ctx ([], "Float") [] p
+	| TFloat -> mk_type_path ctx ([], "Single") [] p
+	| TInt -> mk_type_path ctx ([], "Int") [] p
+	| TLong -> mk_type_path ctx (["haxe"], "Int64") [] p
+	| TShort -> mk_type_path ctx (["java"; "types"], "Int16") [] p
+	| TBool -> mk_type_path ctx ([], "Bool") [] p
+	| TObject ( (["haxe";"root"], name), args ) -> mk_type_path ctx ([], name) (List.map (convert_arg ctx p) args) p
 	(** nullable types *)
 	(** nullable types *)
 	(* replaced from Null<Type> to the actual abstract type to fix #2738 *)
 	(* replaced from Null<Type> to the actual abstract type to fix #2738 *)
 	(* | TObject ( (["java";"lang"], "Integer"), [] ) -> mk_type_path ctx ([], "Null") [ TPType (mk_type_path ctx ([], "Int") []) ] *)
 	(* | TObject ( (["java";"lang"], "Integer"), [] ) -> mk_type_path ctx ([], "Null") [ TPType (mk_type_path ctx ([], "Int") []) ] *)
@@ -140,34 +140,34 @@ and convert_signature ctx p jsig =
 	(* | TObject ( (["java";"lang"], "Short"), [] ) -> mk_type_path ctx ([], "Null") [ TPType (mk_type_path ctx (["java";"types"], "Int16") []) ] *)
 	(* | TObject ( (["java";"lang"], "Short"), [] ) -> mk_type_path ctx ([], "Null") [ TPType (mk_type_path ctx (["java";"types"], "Int16") []) ] *)
 	(* | TObject ( (["java";"lang"], "Long"), [] ) -> mk_type_path ctx ([], "Null") [ TPType (mk_type_path ctx (["haxe"], "Int64") []) ] *)
 	(* | TObject ( (["java";"lang"], "Long"), [] ) -> mk_type_path ctx ([], "Null") [ TPType (mk_type_path ctx (["haxe"], "Int64") []) ] *)
 	(** other std types *)
 	(** other std types *)
-	| TObject ( (["java";"lang"], "Object"), [] ) -> mk_type_path ctx ([], "Dynamic") []
-	| TObject ( (["java";"lang"], "String"), [] ) -> mk_type_path ctx ([], "String") []
-	| TObject ( (["java";"lang"], "Enum"), [_] ) -> mk_type_path ctx ([], "EnumValue") []
+	| TObject ( (["java";"lang"], "Object"), [] ) -> mk_type_path ctx ([], "Dynamic") [] p
+	| TObject ( (["java";"lang"], "String"), [] ) -> mk_type_path ctx ([], "String") [] p
+	| TObject ( (["java";"lang"], "Enum"), [_] ) -> mk_type_path ctx ([], "EnumValue") [] p
 	(** other types *)
 	(** other types *)
 	| TObject ( path, [] ) ->
 	| TObject ( path, [] ) ->
 		(match lookup_jclass ctx.jcom path with
 		(match lookup_jclass ctx.jcom path with
-		| Some (jcl, _, _) -> mk_type_path ctx path (List.map (fun _ -> convert_arg ctx p TAny) jcl.ctypes)
-		| None -> mk_type_path ctx path [])
-	| TObject ( path, args ) -> mk_type_path ctx path (List.map (convert_arg ctx p) args)
+		| Some (jcl, _, _) -> mk_type_path ctx path (List.map (fun _ -> convert_arg ctx p TAny) jcl.ctypes) p
+		| None -> mk_type_path ctx path [] p)
+	| TObject ( path, args ) -> mk_type_path ctx path (List.map (convert_arg ctx p) args) p
 	| TObjectInner (pack, (name, params) :: inners) ->
 	| TObjectInner (pack, (name, params) :: inners) ->
 			let actual_param = match List.rev inners with
 			let actual_param = match List.rev inners with
 			| (_, p) :: _ -> p
 			| (_, p) :: _ -> p
 			| _ -> die "" __LOC__ in
 			| _ -> die "" __LOC__ in
-			mk_type_path ctx (pack, name ^ "$" ^ String.concat "$" (List.map fst inners)) (List.map (fun param -> convert_arg ctx p param) actual_param)
+			mk_type_path ctx (pack, name ^ "$" ^ String.concat "$" (List.map fst inners)) (List.map (fun param -> convert_arg ctx p param) actual_param) p
 	| TObjectInner (pack, inners) -> die "" __LOC__
 	| TObjectInner (pack, inners) -> die "" __LOC__
-	| TArray (jsig, _) -> mk_type_path ctx (["java"], "NativeArray") [ TPType (convert_signature ctx p jsig,null_pos) ]
+	| TArray (jsig, _) -> mk_type_path ctx (["java"], "NativeArray") [ TPType (convert_signature ctx p jsig,null_pos) ] p
 	| TMethod _ -> JReader.error "TMethod cannot be converted directly into Complex Type"
 	| TMethod _ -> JReader.error "TMethod cannot be converted directly into Complex Type"
 	| TTypeParameter s -> (match ctx.jtparams with
 	| TTypeParameter s -> (match ctx.jtparams with
 		| cur :: others ->
 		| cur :: others ->
 			if has_tparam s cur then
 			if has_tparam s cur then
-				mk_type_path ctx ([], s) []
+				mk_type_path ctx ([], s) [] p
 			else begin
 			else begin
 				if ctx.jcom.verbose && not(List.exists (has_tparam s) others) then print_endline ("Type parameter " ^ s ^ " was not found while building type!");
 				if ctx.jcom.verbose && not(List.exists (has_tparam s) others) then print_endline ("Type parameter " ^ s ^ " was not found while building type!");
-				mk_type_path ctx ([], "Dynamic") []
+				mk_type_path ctx ([], "Dynamic") [] p
 			end
 			end
 		| _ ->
 		| _ ->
 			if ctx.jcom.verbose then print_endline ("Empty type parameter stack!");
 			if ctx.jcom.verbose then print_endline ("Empty type parameter stack!");
-			mk_type_path ctx ([], "Dynamic") [])
+			mk_type_path ctx ([], "Dynamic") [] p)
 
 
 let convert_constant ctx p const =
 let convert_constant ctx p const =
 	Option.map_default (function
 	Option.map_default (function
@@ -196,7 +196,7 @@ let convert_param ctx p parent param =
 			tp_meta = [];
 			tp_meta = [];
 		}
 		}
 
 
-let get_type_path ctx ct = match ct with | CTPath p -> p | _ -> die "" __LOC__
+let get_type_path ctx ct = match ct with | CTPath ptp -> ptp | _ -> die "" __LOC__
 
 
 let is_override field =
 let is_override field =
 	List.exists (function | AttrVisibleAnnotations [{ ann_type = TObject( (["java";"lang"], "Override"), _ ) }] -> true | _ -> false) field.jf_attributes
 	List.exists (function | AttrVisibleAnnotations [{ ann_type = TObject( (["java";"lang"], "Override"), _ ) }] -> true | _ -> false) field.jf_attributes
@@ -308,6 +308,7 @@ let convert_java_enum ctx p pe =
 		List.iter (fun jsig ->
 		List.iter (fun jsig ->
 			match convert_signature ctx p jsig with
 			match convert_signature ctx p jsig with
 				| CTPath path ->
 				| CTPath path ->
+					let path = path.path in
 					cff_meta := (Meta.Throws, [Ast.EConst (Ast.String (s_type_path (path.tpackage,path.tname),SDoubleQuotes)), p],p) :: !cff_meta
 					cff_meta := (Meta.Throws, [Ast.EConst (Ast.String (s_type_path (path.tpackage,path.tname),SDoubleQuotes)), p],p) :: !cff_meta
 				| _ -> ()
 				| _ -> ()
 		) field.jf_throws;
 		) field.jf_throws;
@@ -360,13 +361,13 @@ let convert_java_enum ctx p pe =
 						let hx_sig =
 						let hx_sig =
 							match s with
 							match s with
 							| TArray (s1,_) when !is_varargs && !i = args_count && is_eligible_for_haxe_rest_args s1 ->
 							| TArray (s1,_) when !is_varargs && !i = args_count && is_eligible_for_haxe_rest_args s1 ->
-								mk_type_path ctx (["haxe"], "Rest") [TPType (convert_signature ctx p s1,null_pos)]
+								mk_type_path ctx (["haxe"], "Rest") [TPType (convert_signature ctx p s1,null_pos)] p
 							| _ ->
 							| _ ->
 								convert_signature ctx null_pos s
 								convert_signature ctx null_pos s
 						in
 						in
 						(local_names !i,null_pos), false, [], Some(hx_sig,null_pos), None
 						(local_names !i,null_pos), false, [], Some(hx_sig,null_pos), None
 					) args in
 					) args in
-					let t = Option.map_default (convert_signature ctx p) (mk_type_path ctx ([], "Void") []) ret in
+					let t = Option.map_default (convert_signature ctx p) (mk_type_path ctx ([], "Void") [] p) ret in
 					cff_access := (AOverload,p) :: !cff_access;
 					cff_access := (AOverload,p) :: !cff_access;
 					let types = List.map (function
 					let types = List.map (function
 						| (name, Some ext, impl) ->
 						| (name, Some ext, impl) ->
@@ -485,7 +486,7 @@ let convert_java_enum ctx p pe =
 			(match jc.csuper with
 			(match jc.csuper with
 				| TObject( (["java";"lang"], "Object"), _ ) -> ()
 				| TObject( (["java";"lang"], "Object"), _ ) -> ()
 				| TObject( (["haxe";"lang"], "HxObject"), _ ) -> meta := (Meta.HxGen,[],p) :: !meta
 				| TObject( (["haxe";"lang"], "HxObject"), _ ) -> meta := (Meta.HxGen,[],p) :: !meta
-				| _ -> flags := HExtends (get_type_path ctx (convert_signature ctx p jc.csuper),null_pos) :: !flags
+				| _ -> flags := HExtends (get_type_path ctx (convert_signature ctx p jc.csuper)) :: !flags
 			);
 			);
 
 
 			List.iter (fun i ->
 			List.iter (fun i ->
@@ -493,9 +494,9 @@ let convert_java_enum ctx p pe =
 				| TObject ( (["haxe";"lang"], "IHxObject"), _ ) -> meta := (Meta.HxGen,[],p) :: !meta
 				| TObject ( (["haxe";"lang"], "IHxObject"), _ ) -> meta := (Meta.HxGen,[],p) :: !meta
 				| _ -> flags :=
 				| _ -> flags :=
 					if !is_interface then
 					if !is_interface then
-						HExtends (get_type_path ctx (convert_signature ctx p i),null_pos) :: !flags
+						HExtends (get_type_path ctx (convert_signature ctx p i)) :: !flags
 					else
 					else
-						HImplements (get_type_path ctx (convert_signature ctx p i),null_pos) :: !flags
+						HImplements (get_type_path ctx (convert_signature ctx p i)) :: !flags
 			) jc.cinterfaces;
 			) jc.cinterfaces;
 
 
 			let fields = ref [] in
 			let fields = ref [] in
@@ -520,6 +521,7 @@ let convert_java_enum ctx p pe =
 					match convert_signature ctx p jsig with
 					match convert_signature ctx p jsig with
 						| CTPath path ->
 						| CTPath path ->
 							let pos = { p with pfile = p.pfile ^ " (" ^ f.jf_name ^" @:throws)" } in
 							let pos = { p with pfile = p.pfile ^ " (" ^ f.jf_name ^" @:throws)" } in
+							let path = path.path in
 							EImport( List.map (fun s -> s,pos) (path.tpackage @ [path.tname]), INormal )
 							EImport( List.map (fun s -> s,pos) (path.tpackage @ [path.tname]), INormal )
 						| _ -> die "" __LOC__
 						| _ -> die "" __LOC__
 				) f.jf_throws
 				) f.jf_throws
@@ -1069,19 +1071,19 @@ class virtual java_library com name file_path = object(self)
 														d_params = c.d_params;
 														d_params = c.d_params;
 														d_meta = [];
 														d_meta = [];
 														d_flags = [];
 														d_flags = [];
-														d_data = CTPath {
+														d_data = make_ptp_th_null {
 															tpackage = pack;
 															tpackage = pack;
 															tname = snd path;
 															tname = snd path;
 															tparams = List.map (fun tp ->
 															tparams = List.map (fun tp ->
-																TPType (CTPath {
+																TPType (make_ptp_th_null {
 																	tpackage = [];
 																	tpackage = [];
 																	tname = fst tp.tp_name;
 																	tname = fst tp.tp_name;
 																	tparams = [];
 																	tparams = [];
 																	tsub = None;
 																	tsub = None;
-																},null_pos)
+																})
 															) c.d_params;
 															) c.d_params;
 															tsub = Some(fst c.d_name);
 															tsub = Some(fst c.d_name);
-														},null_pos;
+														};
 													} in
 													} in
 													inner_alias := SS.add alias_name !inner_alias;
 													inner_alias := SS.add alias_name !inner_alias;
 													alias_list := (alias_def, pos) :: !alias_list;
 													alias_list := (alias_def, pos) :: !alias_list;

+ 69 - 33
src/codegen/javaModern.ml

@@ -18,6 +18,7 @@ module AccessFlags = struct
 		| MAbstract
 		| MAbstract
 		| MStrict
 		| MStrict
 		| MSynthetic
 		| MSynthetic
+		| MAnnotation
 		| MEnum
 		| MEnum
 
 
 	let to_int = function
 	let to_int = function
@@ -34,6 +35,7 @@ module AccessFlags = struct
 		| MAbstract -> 0x400
 		| MAbstract -> 0x400
 		| MStrict -> 0x800
 		| MStrict -> 0x800
 		| MSynthetic -> 0x1000
 		| MSynthetic -> 0x1000
+		| MAnnotation -> 0x2000
 		| MEnum -> 0x4000
 		| MEnum -> 0x4000
 
 
 	let has_flag b flag =
 	let has_flag b flag =
@@ -422,7 +424,7 @@ module JReaderModern = struct
 			let len = read_i32 ch in
 			let len = read_i32 ch in
 			ignore(IO.nread_string ch len); (* code *)
 			ignore(IO.nread_string ch len); (* code *)
 			let len = read_ui16 ch in
 			let len = read_ui16 ch in
-			for i = 0 to len - 1 do
+			for _ = 0 to len - 1 do
 				ignore(IO.nread_string ch 8);
 				ignore(IO.nread_string ch 8);
 			done; (* exceptions *)
 			done; (* exceptions *)
 			let attribs = parse_attributes consts ch in
 			let attribs = parse_attributes consts ch in
@@ -555,7 +557,7 @@ module PathConverter = struct
 	let jname_to_hx name =
 	let jname_to_hx name =
 		let name =
 		let name =
 			if name <> "" && (String.get name 0 < 'A' || String.get name 0 > 'Z') then
 			if name <> "" && (String.get name 0 < 'A' || String.get name 0 > 'Z') then
-				Char.escaped (Char.uppercase (String.get name 0)) ^ String.sub name 1 (String.length name - 1)
+				Char.escaped (Char.uppercase_ascii (String.get name 0)) ^ String.sub name 1 (String.length name - 1)
 			else
 			else
 				name
 				name
 		in
 		in
@@ -615,46 +617,48 @@ type java_lib_ctx = {
 module SignatureConverter = struct
 module SignatureConverter = struct
 	open PathConverter
 	open PathConverter
 
 
-	let mk_type_path path params =
+	let mk_type_path path params p =
 		let pack,(mname,name) = jpath_to_hx path in
 		let pack,(mname,name) = jpath_to_hx path in
-		match mname with
+		let path = match mname with
 		| None ->
 		| None ->
-			CTPath {
+			{
 				tpackage = pack;
 				tpackage = pack;
 				tname = name;
 				tname = name;
 				tparams = params;
 				tparams = params;
 				tsub = None;
 				tsub = None;
 			}
 			}
 		| Some mname ->
 		| Some mname ->
-			CTPath {
+			{
 				tpackage = pack;
 				tpackage = pack;
 				tname = mname;
 				tname = mname;
 				tparams = params;
 				tparams = params;
 				tsub = Some name;
 				tsub = Some name;
 			}
 			}
+		in
+		make_ptp_ct path p
 
 
-	let ct_type_param name = CTPath {
+	let ct_type_param name = make_ptp_ct_null {
 		tpackage = [];
 		tpackage = [];
 		tname = name;
 		tname = name;
 		tparams = [];
 		tparams = [];
 		tsub = None
 		tsub = None
 	}
 	}
 
 
-	let ct_void = CTPath {
+	let ct_void = make_ptp_ct_null {
 		tpackage = [];
 		tpackage = [];
 		tname = "Void";
 		tname = "Void";
 		tparams = [];
 		tparams = [];
 		tsub = None;
 		tsub = None;
 	}
 	}
 
 
-	let ct_dynamic = CTPath {
+	let ct_dynamic = make_ptp_ct_null {
 		tpackage = [];
 		tpackage = [];
 		tname = "Dynamic";
 		tname = "Dynamic";
 		tparams = [];
 		tparams = [];
 		tsub = None;
 		tsub = None;
 	}
 	}
 
 
-	let ct_string = CTPath {
+	let ct_string = make_ptp_ct_null {
 		tpackage = [];
 		tpackage = [];
 		tname = "String";
 		tname = "String";
 		tparams = [];
 		tparams = [];
@@ -663,33 +667,33 @@ module SignatureConverter = struct
 
 
 	let rec convert_arg ctx p arg =
 	let rec convert_arg ctx p arg =
 		match arg with
 		match arg with
-		| TAny | TType (WSuper, _) -> TPType (mk_type_path ([], "Dynamic") [],p)
+		| TAny | TType (WSuper, _) -> TPType (mk_type_path ([], "Dynamic") [] p,p)
 		| TType (_, jsig) -> TPType (convert_signature ctx p jsig,p)
 		| TType (_, jsig) -> TPType (convert_signature ctx p jsig,p)
 
 
 	and convert_signature ctx p jsig =
 	and convert_signature ctx p jsig =
 		match jsig with
 		match jsig with
-		| TByte -> mk_type_path (["java"; "types"], "Int8") []
-		| TChar -> mk_type_path (["java"; "types"], "Char16") []
-		| TDouble -> mk_type_path ([], "Float") []
-		| TFloat -> mk_type_path ([], "Single") []
-		| TInt -> mk_type_path ([], "Int") []
-		| TLong -> mk_type_path (["haxe"], "Int64") []
-		| TShort -> mk_type_path (["java"; "types"], "Int16") []
-		| TBool -> mk_type_path ([], "Bool") []
-		| TObject ( (["haxe";"root"], name), args ) -> mk_type_path ([], name) (List.map (convert_arg ctx p) args)
-		| TObject ( (["java";"lang"], "Object"), [] ) -> mk_type_path ([], "Dynamic") []
-		| TObject ( (["java";"lang"], "String"), [] ) -> mk_type_path ([], "String") []
-		| TObject ( (["java";"lang"], "Enum"), [_] ) -> mk_type_path ([], "EnumValue") []
+		| TByte -> mk_type_path (["java"; "types"], "Int8") [] p
+		| TChar -> mk_type_path (["java"; "types"], "Char16") [] p
+		| TDouble -> mk_type_path ([], "Float") [] p
+		| TFloat -> mk_type_path ([], "Single") [] p
+		| TInt -> mk_type_path ([], "Int") [] p
+		| TLong -> mk_type_path (["haxe"], "Int64") [] p
+		| TShort -> mk_type_path (["java"; "types"], "Int16") [] p
+		| TBool -> mk_type_path ([], "Bool") [] p
+		| TObject ( (["haxe";"root"], name), args ) -> mk_type_path ([], name) (List.map (convert_arg ctx p) args) p
+		| TObject ( (["java";"lang"], "Object"), [] ) -> mk_type_path ([], "Dynamic") [] p
+		| TObject ( (["java";"lang"], "String"), [] ) -> mk_type_path ([], "String") [] p
+		| TObject ( (["java";"lang"], "Enum"), [_] ) -> mk_type_path ([], "EnumValue") [] p
 		| TObject ( path, [] ) ->
 		| TObject ( path, [] ) ->
-			mk_type_path path []
-		| TObject ( path, args ) -> mk_type_path path (List.map (convert_arg ctx p) args)
+			mk_type_path path [] p
+		| TObject ( path, args ) -> mk_type_path path (List.map (convert_arg ctx p) args) p
 		| TObjectInner (pack, (name, params) :: inners) ->
 		| TObjectInner (pack, (name, params) :: inners) ->
 			let actual_param = match List.rev inners with
 			let actual_param = match List.rev inners with
 			| (_, p) :: _ -> p
 			| (_, p) :: _ -> p
 			| _ -> die "" __LOC__ in
 			| _ -> die "" __LOC__ in
-			mk_type_path (pack, name ^ "$" ^ String.concat "$" (List.map fst inners)) (List.map (fun param -> convert_arg ctx p param) actual_param)
+			mk_type_path (pack, name ^ "$" ^ String.concat "$" (List.map fst inners)) (List.map (fun param -> convert_arg ctx p param) actual_param) p
 		| TObjectInner (pack, inners) -> die "" __LOC__
 		| TObjectInner (pack, inners) -> die "" __LOC__
-		| TArray (jsig, _) -> mk_type_path (["java"], "NativeArray") [ TPType (convert_signature ctx p jsig,p) ]
+		| TArray (jsig, _) -> mk_type_path (["java"], "NativeArray") [ TPType (convert_signature ctx p jsig,p) ] p
 		| TMethod _ -> failwith "TMethod cannot be converted directly into Complex Type"
 		| TMethod _ -> failwith "TMethod cannot be converted directly into Complex Type"
 		| TTypeParameter s ->
 		| TTypeParameter s ->
 			try
 			try
@@ -698,7 +702,7 @@ module SignatureConverter = struct
 				ct_dynamic
 				ct_dynamic
 end
 end
 
 
-let get_type_path ct = match ct with | CTPath p -> p | _ -> die "" __LOC__
+let get_type_path ct = match ct with | CTPath ptp -> ptp | _ -> die "" __LOC__
 
 
 module Converter = struct
 module Converter = struct
 
 
@@ -706,6 +710,27 @@ module Converter = struct
 	open PathConverter
 	open PathConverter
 	open SignatureConverter
 	open SignatureConverter
 
 
+	let extract_retention_policy l =
+		let rec loop2 l = match l with
+			| [] ->
+				None
+			| ann :: l ->
+				match ann.ann_type,ann.ann_elements with
+				| TObject((["java";"lang";"annotation"],"Retention"),_),[("value",ValEnum(_,name))] ->
+					Some name
+				| _ ->
+					loop2 l
+		in
+		let rec loop l = match l with
+			| [] ->
+				None
+			| AttrVisibleAnnotations l :: _ ->
+				loop2 l
+			| _ :: l ->
+				loop l
+		in
+		loop l
+
 	let convert_type_parameter ctx (name,extends,implements) p =
 	let convert_type_parameter ctx (name,extends,implements) p =
 		let jsigs = match extends with
 		let jsigs = match extends with
 			| Some jsig -> jsig :: implements
 			| Some jsig -> jsig :: implements
@@ -867,7 +892,7 @@ module Converter = struct
 						let hx_sig =
 						let hx_sig =
 							match jsig with
 							match jsig with
 							| TArray (jsig1,_) when is_varargs && i + 1 = args_count && is_eligible_for_haxe_rest_args jsig1 ->
 							| TArray (jsig1,_) when is_varargs && i + 1 = args_count && is_eligible_for_haxe_rest_args jsig1 ->
-								mk_type_path (["haxe"], "Rest") [TPType (convert_signature ctx p jsig1,p)]
+								mk_type_path (["haxe"], "Rest") [TPType (convert_signature ctx p jsig1,p)] p
 							| _ ->
 							| _ ->
 								convert_signature ctx p jsig
 								convert_signature ctx p jsig
 						in
 						in
@@ -908,15 +933,17 @@ module Converter = struct
 		let is_interface = AccessFlags.has_flag jc.jc_flags MInterface in
 		let is_interface = AccessFlags.has_flag jc.jc_flags MInterface in
 		if is_interface then add_flag HInterface
 		if is_interface then add_flag HInterface
 		else if AccessFlags.has_flag jc.jc_flags MAbstract then add_flag HAbstract;
 		else if AccessFlags.has_flag jc.jc_flags MAbstract then add_flag HAbstract;
+		let is_annotation = AccessFlags.has_flag jc.jc_flags MAnnotation in
 		begin match jc.jc_super with
 		begin match jc.jc_super with
 			| TObject(([],""),_)
 			| TObject(([],""),_)
 			| TObject((["java";"lang"],"Object"),_) ->
 			| TObject((["java";"lang"],"Object"),_) ->
-				()
+				if is_annotation then
+					add_flag (HExtends (make_ptp {tpackage = ["java";"lang";"annotation"]; tname = "Annotation"; tsub = None; tparams = []} p))
 			| jsig ->
 			| jsig ->
-				add_flag (HExtends (get_type_path (convert_signature ctx p jsig),p))
+				add_flag (HExtends (get_type_path (convert_signature ctx p jsig)))
 		end;
 		end;
 		List.iter (fun jsig ->
 		List.iter (fun jsig ->
-			let path = (get_type_path (convert_signature ctx p jsig),p) in
+			let path = get_type_path (convert_signature ctx p jsig) in
 			if is_interface then
 			if is_interface then
 				add_flag (HExtends path)
 				add_flag (HExtends path)
 			else
 			else
@@ -957,6 +984,15 @@ module Converter = struct
 		end;
 		end;
 		let _,class_name = jname_to_hx (snd jc.jc_path) in
 		let _,class_name = jname_to_hx (snd jc.jc_path) in
 		add_meta (Meta.Native, [EConst (String (s_type_path jc.jc_path,SDoubleQuotes) ),p],p);
 		add_meta (Meta.Native, [EConst (String (s_type_path jc.jc_path,SDoubleQuotes) ),p],p);
+		if is_annotation then begin
+			let args = match extract_retention_policy jc.jc_attributes with
+				| None ->
+					[]
+				| Some v ->
+					[EConst (String(v,SDoubleQuotes)),p]
+			in
+			add_meta (Meta.Annotation,args,p)
+		end;
 		let d = {
 		let d = {
 			d_name = (class_name,p);
 			d_name = (class_name,p);
 			d_doc = None;
 			d_doc = None;
@@ -1056,4 +1092,4 @@ class java_library_modern com name file_path = object(self)
 		build path
 		build path
 
 
 	method get_data = ()
 	method get_data = ()
-end
+end

+ 4 - 13
src/codegen/overloads.ml

@@ -1,6 +1,6 @@
 open Globals
 open Globals
 open Type
 open Type
-open Typecore
+open FieldCallCandidate
 
 
 let same_overload_args ?(get_vmtype) t1 t2 f1 f2 =
 let same_overload_args ?(get_vmtype) t1 t2 f1 f2 =
 	let f_transform = match get_vmtype with
 	let f_transform = match get_vmtype with
@@ -13,13 +13,10 @@ let same_overload_args ?(get_vmtype) t1 t2 f1 f2 =
 			| [],[] ->
 			| [],[] ->
 				true
 				true
 			| tp1 :: params1,tp2 :: params2 ->
 			| tp1 :: params1,tp2 :: params2 ->
-				let constraints_equal t1 t2 = match follow t1,follow t2 with
-					| TInst({cl_kind = KTypeParameter tl1},_),TInst({cl_kind = KTypeParameter tl2},_) ->
-						Ast.safe_for_all2 f_eq tl1 tl2
-					| _ ->
-						false
+				let constraints_equal ttp1 ttp2 = 
+					Ast.safe_for_all2 f_eq (get_constraints ttp2) (get_constraints ttp2)
 				in
 				in
-				tp1.ttp_name = tp2.ttp_name && constraints_equal tp1.ttp_type tp2.ttp_type && loop params1 params2
+				tp1.ttp_name = tp2.ttp_name && constraints_equal tp1 tp2 && loop params1 params2
 			| [],_
 			| [],_
 			| _,[] ->
 			| _,[] ->
 				false
 				false
@@ -219,12 +216,6 @@ struct
 		| r :: ret ->
 		| r :: ret ->
 			rm_duplicates (r :: acc) ret
 			rm_duplicates (r :: acc) ret
 
 
-	let s_options rated =
-		String.concat ",\n" (List.map (fun ((elist,t,_),rate) ->
-			"( " ^ (String.concat "," (List.map (fun(e,_) -> s_expr (s_type (print_context())) e) elist)) ^ " ) => " ^
-			"( " ^ (String.concat "," (List.map (fun (i,i2) -> string_of_int i ^ ":" ^ string_of_int i2) rate)) ^ " ) => " ^ (s_type (print_context()) t)
-		) rated)
-
 	let count_optionals t =
 	let count_optionals t =
 		match follow t with
 		match follow t with
 		| TFun(args,_) ->
 		| TFun(args,_) ->

+ 21 - 17
src/codegen/swfLoader.ml

@@ -33,7 +33,7 @@ let lowercase_pack pack =
 			let name =
 			let name =
 				let fchar = String.get name 0 in
 				let fchar = String.get name 0 in
 				if fchar >= 'A' && fchar <= 'Z' then
 				if fchar >= 'A' && fchar <= 'Z' then
-					(String.make 1 (Char.lowercase fchar)) ^ String.sub name 1 (String.length name - 1)
+					(String.make 1 (Char.lowercase_ascii fchar)) ^ String.sub name 1 (String.length name - 1)
 				else
 				else
 					name
 					name
 			in
 			in
@@ -42,18 +42,19 @@ let lowercase_pack pack =
 	loop [] pack
 	loop [] pack
 
 
 
 
-let tp_dyn = { tpackage = []; tname = "Dynamic"; tparams = []; tsub = None; }
+let tp_dyn = make_ptp { tpackage = []; tname = "Dynamic"; tparams = []; tsub = None; } null_pos
 
 
 let ct_dyn = CTPath tp_dyn
 let ct_dyn = CTPath tp_dyn
 
 
-let ct_rest = CTPath {
+let ct_rest = make_ptp_ct_null {
 	tpackage = ["haxe"];
 	tpackage = ["haxe"];
 	tname = "Rest";
 	tname = "Rest";
 	tparams = [TPType (ct_dyn,null_pos)];
 	tparams = [TPType (ct_dyn,null_pos)];
 	tsub = None;
 	tsub = None;
 }
 }
 
 
-let rec make_tpath = function
+let rec make_tpath x =
+	let path = match x with
 	| HMPath (pack,name) ->
 	| HMPath (pack,name) ->
 		let pdyn = ref false in
 		let pdyn = ref false in
 		let pack, name = match pack, name with
 		let pack, name = match pack, name with
@@ -116,7 +117,10 @@ let rec make_tpath = function
 		die "" __LOC__
 		die "" __LOC__
 	| HMParams (t,params) ->
 	| HMParams (t,params) ->
 		let params = List.map (fun t -> TPType (CTPath (make_tpath t),null_pos)) params in
 		let params = List.map (fun t -> TPType (CTPath (make_tpath t),null_pos)) params in
-		{ (make_tpath t) with tparams = params }
+		let ptp = make_tpath t in
+		{ptp.path with tparams = params}
+	in
+	make_ptp path null_pos
 
 
 let make_topt = function
 let make_topt = function
 	| None -> tp_dyn
 	| None -> tp_dyn
@@ -126,7 +130,7 @@ let make_type t = CTPath (make_topt t)
 
 
 let make_dyn_type t =
 let make_dyn_type t =
 	match make_topt t with
 	match make_topt t with
-	| { tpackage = ["flash";"utils"]; tname = ("Object"|"Function") } -> make_type None
+	| {path = { tpackage = ["flash";"utils"]; tname = ("Object"|"Function") }} -> make_type None
 	| o -> CTPath o
 	| o -> CTPath o
 
 
 let is_valid_path com pack name =
 let is_valid_path com pack name =
@@ -142,7 +146,7 @@ let is_valid_path com pack name =
 	loop com.load_extern_type || (try ignore(Common.find_file com file); true with Not_found -> false)
 	loop com.load_extern_type || (try ignore(Common.find_file com file); true with Not_found -> false)
 
 
 let build_class com c file =
 let build_class com c file =
-	let path = make_tpath c.hlc_name in
+	let path = (make_tpath c.hlc_name).path in
 	let pos = { pfile = file ^ "@" ^ s_type_path (path.tpackage,path.tname); pmin = 0; pmax = 0 } in
 	let pos = { pfile = file ^ "@" ^ s_type_path (path.tpackage,path.tname); pmin = 0; pmax = 0 } in
 	match path with
 	match path with
 	| { tpackage = ["flash";"utils"]; tname = ("Object"|"Function") } ->
 	| { tpackage = ["flash";"utils"]; tname = ("Object"|"Function") } ->
@@ -162,7 +166,7 @@ let build_class com c file =
 	let flags = (match c.hlc_super with
 	let flags = (match c.hlc_super with
 		| None | Some (HMPath ([],"Object")) -> flags
 		| None | Some (HMPath ([],"Object")) -> flags
 		| Some (HMPath ([],"Function")) -> flags (* found in AIR SDK *)
 		| Some (HMPath ([],"Function")) -> flags (* found in AIR SDK *)
-		| Some s -> HExtends (make_tpath s,null_pos) :: flags
+		| Some s -> HExtends (make_tpath s) :: flags
 	) in
 	) in
 	let flags = List.map (fun i ->
 	let flags = List.map (fun i ->
 		let i = (match i with
 		let i = (match i with
@@ -176,9 +180,9 @@ let build_class com c file =
 			| HMPath _ -> i
 			| HMPath _ -> i
 			| _ -> die "" __LOC__
 			| _ -> die "" __LOC__
 		) in
 		) in
-		if c.hlc_interface then HExtends (make_tpath i,null_pos) else HImplements (make_tpath i,null_pos)
+		if c.hlc_interface then HExtends (make_tpath i) else HImplements (make_tpath i)
 	) (Array.to_list c.hlc_implements) @ flags in
 	) (Array.to_list c.hlc_implements) @ flags in
-	let flags = if c.hlc_sealed || Common.defined com Define.FlashStrict then flags else HImplements (tp_dyn,null_pos) :: flags in
+	let flags = if c.hlc_sealed || Common.defined com Define.FlashStrict then flags else HImplements tp_dyn :: flags in
 	(* make fields *)
 	(* make fields *)
 	let getters = Hashtbl.create 0 in
 	let getters = Hashtbl.create 0 in
 	let setters = Hashtbl.create 0 in
 	let setters = Hashtbl.create 0 in
@@ -209,7 +213,7 @@ let build_class com c file =
 		) in
 		) in
 		if flags = [] then acc else
 		if flags = [] then acc else
 		let flags = if stat then (AStatic,null_pos) :: flags else flags in
 		let flags = if stat then (AStatic,null_pos) :: flags else flags in
-		let name = (make_tpath f.hlf_name).tname in
+		let name = (make_tpath f.hlf_name).path.tname in
 		let mk_meta() =
 		let mk_meta() =
 			List.map (fun (s,cl) -> s, List.map (fun c -> EConst c,pos) cl, pos) (!meta)
 			List.map (fun (s,cl) -> s, List.map (fun c -> EConst c,pos) cl, pos) (!meta)
 		in
 		in
@@ -395,8 +399,8 @@ let build_class com c file =
 			| [] -> []
 			| [] -> []
 			| f :: l ->
 			| f :: l ->
 				match f.cff_kind with
 				match f.cff_kind with
-				| FVar (Some ((CTPath { tpackage = []; tname = ("String" | "Int" | "UInt")} as real_t),_),None)
-				| FProp (("default",_),("never",_),Some ((CTPath { tpackage = []; tname = ("String" | "Int" | "UInt")}) as real_t,_),None) when List.mem_assoc AStatic f.cff_access ->
+				| FVar (Some ((CTPath {path = { tpackage = []; tname = ("String" | "Int" | "UInt")}} as real_t),_),None)
+				| FProp (("default",_),("never",_),Some ((CTPath { path = { tpackage = []; tname = ("String" | "Int" | "UInt")}}) as real_t,_),None) when List.mem_assoc AStatic f.cff_access ->
 					(match !real_type with
 					(match !real_type with
 					| None ->
 					| None ->
 						real_type := Some real_t
 						real_type := Some real_t
@@ -454,10 +458,10 @@ let build_class com c file =
 let extract_data (_,tags) =
 let extract_data (_,tags) =
 	let t = Timer.timer ["read";"swf"] in
 	let t = Timer.timer ["read";"swf"] in
 	let h = Hashtbl.create 0 in
 	let h = Hashtbl.create 0 in
-	let rec loop_field f =
+	let loop_field f =
 		match f.hlf_kind with
 		match f.hlf_kind with
 		| HFClass c ->
 		| HFClass c ->
-			let path = make_tpath f.hlf_name in
+			let path = (make_tpath f.hlf_name).path in
 			(match path with
 			(match path with
 			| { tpackage = []; tname = "Float" | "Bool" | "Int" | "UInt" | "Dynamic" } -> ()
 			| { tpackage = []; tname = "Float" | "Bool" | "Int" | "UInt" | "Dynamic" } -> ()
 			| { tpackage = _; tname = "MethodClosure" } -> ()
 			| { tpackage = _; tname = "MethodClosure" } -> ()
@@ -647,10 +651,10 @@ let remove_classes toremove lib l =
 					match t.tdata with
 					match t.tdata with
 					| TActionScript3 (h,data) ->
 					| TActionScript3 (h,data) ->
 						let data = As3hlparse.parse data in
 						let data = As3hlparse.parse data in
-						let rec loop f =
+						let loop f =
 							match f.hlf_kind with
 							match f.hlf_kind with
 							| HFClass _ ->
 							| HFClass _ ->
-								let path = make_tpath f.hlf_name in
+								let path = (make_tpath f.hlf_name).path in
 								not (List.mem (path.tpackage,path.tname) classes)
 								not (List.mem (path.tpackage,path.tname) classes)
 							| _ -> true
 							| _ -> true
 						in
 						in

+ 26 - 13
src/compiler/args.ml

@@ -2,8 +2,10 @@ open Globals
 open Common
 open Common
 open CompilationContext
 open CompilationContext
 
 
+let columns = lazy (match Terminal_size.get_columns () with None -> 80 | Some c -> c)
+
 let limit_string s offset =
 let limit_string s offset =
-	let rest = 80 - offset in
+	let rest = (Lazy.force columns) - offset in
 	let words = ExtString.String.nsplit s " " in
 	let words = ExtString.String.nsplit s " " in
 	let rec loop i words = match words with
 	let rec loop i words = match words with
 		| word :: words ->
 		| word :: words ->
@@ -40,7 +42,7 @@ let process_args arg_spec =
 
 
 let parse_args com =
 let parse_args com =
 	let usage = Printf.sprintf
 	let usage = Printf.sprintf
-		"Haxe Compiler %s - (C)2005-2022 Haxe Foundation\nUsage: haxe%s <target> [options] [hxml files and dot paths...]\n"
+		"Haxe Compiler %s - (C)2005-2024 Haxe Foundation\nUsage: haxe%s <target> [options] [hxml files and dot paths...]\n"
 		s_version_full (if Sys.os_type = "Win32" then ".exe" else "")
 		s_version_full (if Sys.os_type = "Win32" then ".exe" else "")
 	in
 	in
 	let actx = {
 	let actx = {
@@ -64,7 +66,10 @@ let parse_args com =
 	let add_deprecation s =
 	let add_deprecation s =
 		actx.deprecations <- s :: actx.deprecations
 		actx.deprecations <- s :: actx.deprecations
 	in
 	in
-	let add_native_lib file extern = actx.native_libs <- (file,extern) :: actx.native_libs in
+	let add_native_lib file extern kind =
+		let lib = create_native_lib file extern kind in
+		actx.native_libs <- lib :: actx.native_libs
+	in
 	let basic_args_spec = [
 	let basic_args_spec = [
 		("Target",["--js"],["-js"],Arg.String (set_platform com Js),"<file>","generate JavaScript code into target file");
 		("Target",["--js"],["-js"],Arg.String (set_platform com Js),"<file>","generate JavaScript code into target file");
 		("Target",["--lua"],["-lua"],Arg.String (set_platform com Lua),"<file>","generate Lua code into target file");
 		("Target",["--lua"],["-lua"],Arg.String (set_platform com Lua),"<file>","generate Lua code into target file");
@@ -98,6 +103,10 @@ let parse_args com =
 		("Target",["--hl"],["-hl"],Arg.String (fun file ->
 		("Target",["--hl"],["-hl"],Arg.String (fun file ->
 			set_platform com Hl file;
 			set_platform com Hl file;
 		),"<file>","generate HashLink .hl bytecode or .c code into target file");
 		),"<file>","generate HashLink .hl bytecode or .c code into target file");
+		("Target",["--custom-target"],["-custom"],Arg.String (fun target ->
+			let name, path = try let split = ExtString.String.split target "=" in split with _ -> target, "" in
+			set_custom_target com name path;
+		),"<name[=path]>","generate code for a custom target");
 		("Target",[],["-x"], Arg.String (fun cl ->
 		("Target",[],["-x"], Arg.String (fun cl ->
 			let cpath = Path.parse_type_path cl in
 			let cpath = Path.parse_type_path cl in
 			(match com.main_class with
 			(match com.main_class with
@@ -125,12 +134,16 @@ let parse_args com =
 			com.main_class <- Some cpath;
 			com.main_class <- Some cpath;
 			actx.classes <- cpath :: actx.classes
 			actx.classes <- cpath :: actx.classes
 		),"<class>","select startup class");
 		),"<class>","select startup class");
+		("Compilation",["-L";"--library"],["-lib"],Arg.String (fun _ -> ()),"<name[:ver]>","use a haxelib library");
 		("Compilation",["-D";"--define"],[],Arg.String (fun var ->
 		("Compilation",["-D";"--define"],[],Arg.String (fun var ->
 			let flag, value = try let split = ExtString.String.split var "=" in (fst split, Some (snd split)) with _ -> var, None in
 			let flag, value = try let split = ExtString.String.split var "=" in (fst split, Some (snd split)) with _ -> var, None in
 			match value with
 			match value with
 				| Some value -> Common.external_define_value com flag value
 				| Some value -> Common.external_define_value com flag value
 				| None -> Common.external_define com flag;
 				| None -> Common.external_define com flag;
 		),"<var[=value]>","define a conditional compilation flag");
 		),"<var[=value]>","define a conditional compilation flag");
+		("Compilation",["--undefine"],[],Arg.String (fun var ->
+			Common.external_undefine com var
+		),"","remove a conditional compilation flag");
 		("Debug",["-v";"--verbose"],[],Arg.Unit (fun () ->
 		("Debug",["-v";"--verbose"],[],Arg.Unit (fun () ->
 			com.verbose <- true
 			com.verbose <- true
 		),"","turn on verbose mode");
 		),"","turn on verbose mode");
@@ -157,7 +170,7 @@ let parse_args com =
 				let all,max_length = Define.get_user_documentation_list com.user_defines in
 				let all,max_length = Define.get_user_documentation_list com.user_defines in
 				let all = List.map (fun (n,doc) -> Printf.sprintf " %-*s: %s" max_length n (limit_string doc (max_length + 3))) all in
 				let all = List.map (fun (n,doc) -> Printf.sprintf " %-*s: %s" max_length n (limit_string doc (max_length + 3))) all in
 				List.iter (fun msg -> com.print (msg ^ "\n")) all;
 				List.iter (fun msg -> com.print (msg ^ "\n")) all;
-				exit 0
+				raise Abort
 			)
 			)
 		),"","print help for all user defines");
 		),"","print help for all user defines");
 		("Miscellaneous",["--help-metas"],[], Arg.Unit (fun() ->
 		("Miscellaneous",["--help-metas"],[], Arg.Unit (fun() ->
@@ -172,7 +185,7 @@ let parse_args com =
 				let all,max_length = Meta.get_user_documentation_list com.user_metas in
 				let all,max_length = Meta.get_user_documentation_list com.user_metas in
 				let all = List.map (fun (n,doc) -> Printf.sprintf " %-*s: %s" max_length n (limit_string doc (max_length + 3))) all in
 				let all = List.map (fun (n,doc) -> Printf.sprintf " %-*s: %s" max_length n (limit_string doc (max_length + 3))) all in
 				List.iter (fun msg -> com.print (msg ^ "\n")) all;
 				List.iter (fun msg -> com.print (msg ^ "\n")) all;
-				exit 0
+				raise Abort
 			)
 			)
 		),"","print help for all user metadatas");
 		),"","print help for all user metadatas");
 	] in
 	] in
@@ -196,22 +209,22 @@ let parse_args com =
 			Common.define com Define.FlashStrict
 			Common.define com Define.FlashStrict
 		), "","more type strict flash API");
 		), "","more type strict flash API");
 		("Target-specific",["--swf-lib"],["-swf-lib"],Arg.String (fun file ->
 		("Target-specific",["--swf-lib"],["-swf-lib"],Arg.String (fun file ->
-			add_native_lib file false;
+			add_native_lib file false SwfLib;
 		),"<file>","add the SWF library to the compiled SWF");
 		),"<file>","add the SWF library to the compiled SWF");
-		("Target-specific",["--neko-lib"],[],Arg.String (fun file ->
-			com.neko_libs <- file :: com.neko_libs
-		),"<file>","add the neko library");
+		("Target-specific",[],["--neko-lib-path"],Arg.String (fun dir ->
+			com.neko_lib_paths <- dir :: com.neko_lib_paths
+		),"<directory>","add the neko library path");
 		("Target-specific",["--swf-lib-extern"],["-swf-lib-extern"],Arg.String (fun file ->
 		("Target-specific",["--swf-lib-extern"],["-swf-lib-extern"],Arg.String (fun file ->
-			add_native_lib file true;
+			add_native_lib file true SwfLib;
 		),"<file>","use the SWF library for type checking");
 		),"<file>","use the SWF library for type checking");
 		("Target-specific",["--java-lib"],["-java-lib"],Arg.String (fun file ->
 		("Target-specific",["--java-lib"],["-java-lib"],Arg.String (fun file ->
-			add_native_lib file false;
+			add_native_lib file false JavaLib;
 		),"<file>","add an external JAR or directory of JAR files");
 		),"<file>","add an external JAR or directory of JAR files");
 		("Target-specific",["--java-lib-extern"],[],Arg.String (fun file ->
 		("Target-specific",["--java-lib-extern"],[],Arg.String (fun file ->
-			add_native_lib file true;
+			add_native_lib file true JavaLib;
 		),"<file>","use an external JAR or directory of JAR files for type checking");
 		),"<file>","use an external JAR or directory of JAR files for type checking");
 		("Target-specific",["--net-lib"],["-net-lib"],Arg.String (fun file ->
 		("Target-specific",["--net-lib"],["-net-lib"],Arg.String (fun file ->
-			add_native_lib file false;
+			add_native_lib file false NetLib;
 		),"<file>[@std]","add an external .NET DLL file");
 		),"<file>[@std]","add an external .NET DLL file");
 		("Target-specific",["--net-std"],["-net-std"],Arg.String (fun file ->
 		("Target-specific",["--net-std"],["-net-std"],Arg.String (fun file ->
 			Dotnet.add_net_std com file
 			Dotnet.add_net_std com file

+ 28 - 10
src/compiler/compilationContext.ml

@@ -7,6 +7,17 @@ type server_mode =
 	| SMListen of string
 	| SMListen of string
 	| SMConnect of string
 	| SMConnect of string
 
 
+type native_lib_kind =
+	| NetLib
+	| JavaLib
+	| SwfLib
+
+type native_lib_arg = {
+	lib_file : string;
+	lib_kind : native_lib_kind;
+	lib_extern : bool;
+}
+
 type arg_context = {
 type arg_context = {
 	mutable classes : Globals.path list;
 	mutable classes : Globals.path list;
 	mutable xml_out : string option;
 	mutable xml_out : string option;
@@ -20,7 +31,7 @@ type arg_context = {
 	mutable interp : bool;
 	mutable interp : bool;
 	mutable jvm_flag : bool;
 	mutable jvm_flag : bool;
 	mutable swf_version : bool;
 	mutable swf_version : bool;
-	mutable native_libs : (string * bool) list;
+	mutable native_libs : native_lib_arg list;
 	mutable raise_usage : unit -> unit;
 	mutable raise_usage : unit -> unit;
 	mutable display_arg : string option;
 	mutable display_arg : string option;
 	mutable deprecations : string list;
 	mutable deprecations : string list;
@@ -44,7 +55,7 @@ and compilation_context = {
 
 
 type compilation_callbacks = {
 type compilation_callbacks = {
 	before_anything : compilation_context -> unit;
 	before_anything : compilation_context -> unit;
-	after_arg_parsing : compilation_context -> unit;
+	after_target_init : compilation_context -> unit;
 	after_compilation : compilation_context -> unit;
 	after_compilation : compilation_context -> unit;
 }
 }
 
 
@@ -54,20 +65,27 @@ type server_api = {
 	cache : CompilationCache.t;
 	cache : CompilationCache.t;
 	callbacks : compilation_callbacks;
 	callbacks : compilation_callbacks;
 	on_context_create : unit -> int;
 	on_context_create : unit -> int;
-	init_wait_socket : string -> int -> server_accept;
-	init_wait_connect : string -> int -> server_accept;
+	init_wait_socket : (Ipaddr.V4.t, Ipaddr.V6.t) Ipaddr.v4v6 -> int -> server_accept;
+	init_wait_connect : (Ipaddr.V4.t, Ipaddr.V6.t) Ipaddr.v4v6 -> int -> server_accept;
 	init_wait_stdio : unit -> server_accept;
 	init_wait_stdio : unit -> server_accept;
 	wait_loop : bool -> server_accept -> int;
 	wait_loop : bool -> server_accept -> int;
-	do_connect : string -> int -> string list -> unit;
+	do_connect : (Ipaddr.V4.t, Ipaddr.V6.t) Ipaddr.v4v6 -> int -> string list -> unit;
 }
 }
 
 
 let message ctx msg =
 let message ctx msg =
 	ctx.messages <- msg :: ctx.messages
 	ctx.messages <- msg :: ctx.messages
 
 
-let error ctx ?(depth=0) msg p =
-	message ctx (make_compiler_message msg p depth DKCompilerMessage Error);
+let error ctx ?(depth=0) ?(from_macro = false) msg p =
+	message ctx (make_compiler_message ~from_macro msg p depth DKCompilerMessage Error);
 	ctx.has_error <- true
 	ctx.has_error <- true
 
 
-let located_error ctx ?(depth=0) msg =
-	message ctx (make_compiler_message (extract_located_msg msg) (extract_located_pos msg) depth DKCompilerMessage Error);
-	ctx.has_error <- true
+let error_ext ctx (err : Error.error) =
+	Error.recurse_error (fun depth err ->
+		error ~depth ~from_macro:err.err_from_macro ctx (Error.error_msg err.err_message) err.err_pos
+	) err
+
+let create_native_lib file extern kind = {
+	lib_file = file;
+	lib_extern = extern;
+	lib_kind = kind;
+}

+ 153 - 96
src/compiler/compiler.ml

@@ -2,25 +2,35 @@ open Globals
 open Common
 open Common
 open CompilationContext
 open CompilationContext
 
 
-let run_or_diagnose ctx f arg =
+let run_or_diagnose ctx f =
 	let com = ctx.com in
 	let com = ctx.com in
-	let handle_diagnostics msg kind =
+	let handle_diagnostics msg p kind =
 		ctx.has_error <- true;
 		ctx.has_error <- true;
-		add_diagnostics_message com msg kind Error;
-		DisplayOutput.emit_diagnostics ctx.com
+		add_diagnostics_message com msg p kind Error;
+		match com.report_mode with
+		| RMLegacyDiagnostics _ -> DisplayOutput.emit_legacy_diagnostics ctx.com
+		| RMDiagnostics _ -> DisplayOutput.emit_diagnostics ctx.com
+		| _ -> die "" __LOC__
 	in
 	in
 	if is_diagnostics com then begin try
 	if is_diagnostics com then begin try
-			f arg
+			f ()
 		with
 		with
-		| Error.Error(msg,p,_) ->
-			handle_diagnostics (Error.error_msg p msg) DKCompilerMessage
+		| Error.Error err ->
+			ctx.has_error <- true;
+			Error.recurse_error (fun depth err ->
+				add_diagnostics_message ~depth com (Error.error_msg err.err_message) err.err_pos DKCompilerMessage Error
+			) err;
+			(match com.report_mode with
+			| RMLegacyDiagnostics _ -> DisplayOutput.emit_legacy_diagnostics ctx.com
+			| RMDiagnostics _ -> DisplayOutput.emit_diagnostics ctx.com
+			| _ -> die "" __LOC__)
 		| Parser.Error(msg,p) ->
 		| Parser.Error(msg,p) ->
-			handle_diagnostics (located (Parser.error_msg msg) p) DKParserError
+			handle_diagnostics (Parser.error_msg msg) p DKParserError
 		| Lexer.Error(msg,p) ->
 		| Lexer.Error(msg,p) ->
-			handle_diagnostics (located (Lexer.error_msg msg) p) DKParserError
+			handle_diagnostics (Lexer.error_msg msg) p DKParserError
 		end
 		end
 	else
 	else
-		f arg
+		f ()
 
 
 let run_command ctx cmd =
 let run_command ctx cmd =
 	let t = Timer.timer ["command";cmd] in
 	let t = Timer.timer ["command";cmd] in
@@ -67,14 +77,15 @@ let run_command ctx cmd =
 
 
 module Setup = struct
 module Setup = struct
 	let initialize_target ctx com actx =
 	let initialize_target ctx com actx =
+		init_platform com;
 		let add_std dir =
 		let add_std dir =
 			com.class_path <- List.filter (fun s -> not (List.mem s com.std_path)) com.class_path @ List.map (fun p -> p ^ dir ^ "/_std/") com.std_path @ com.std_path
 			com.class_path <- List.filter (fun s -> not (List.mem s com.std_path)) com.class_path @ List.map (fun p -> p ^ dir ^ "/_std/") com.std_path @ com.std_path
 		in
 		in
 		match com.platform with
 		match com.platform with
 			| Cross ->
 			| Cross ->
-				(* no platform selected *)
-				set_platform com Cross "";
 				"?"
 				"?"
+			| CustomTarget name ->
+				name
 			| Flash ->
 			| Flash ->
 				let rec loop = function
 				let rec loop = function
 					| [] -> ()
 					| [] -> ()
@@ -138,13 +149,20 @@ module Setup = struct
 				"python"
 				"python"
 			| Hl ->
 			| Hl ->
 				add_std "hl";
 				add_std "hl";
-				if not (Common.defined com Define.HlVer) then Define.define_value com.defines Define.HlVer (try Std.input_file (Common.find_file com "hl/hl_version") with Not_found -> die "" __LOC__);
+				if not (Common.defined com Define.HlVer) then begin
+					let hl_ver = try
+						Std.input_file (Common.find_file com "hl/hl_version")
+					with Not_found ->
+						failwith "The file hl_version could not be found. Please make sure HAXE_STD_PATH is set to the standard library corresponding to the used compiler version."
+					in
+					Define.define_value com.defines Define.HlVer hl_ver
+				end;
 				"hl"
 				"hl"
 			| Eval ->
 			| Eval ->
 				add_std "eval";
 				add_std "eval";
 				"eval"
 				"eval"
 
 
-	let create_typer_context ctx native_libs =
+	let create_typer_context ctx macros native_libs =
 		let com = ctx.com in
 		let com = ctx.com in
 		Common.log com ("Classpath: " ^ (String.concat ";" com.class_path));
 		Common.log com ("Classpath: " ^ (String.concat ";" com.class_path));
 		let buffer = Buffer.create 64 in
 		let buffer = Buffer.create 64 in
@@ -155,13 +173,12 @@ module Setup = struct
 		) com.defines.values;
 		) com.defines.values;
 		Buffer.truncate buffer (Buffer.length buffer - 1);
 		Buffer.truncate buffer (Buffer.length buffer - 1);
 		Common.log com (Buffer.contents buffer);
 		Common.log com (Buffer.contents buffer);
-		Typecore.type_expr_ref := (fun ?(mode=MGet) ctx e with_type -> Typer.type_expr ~mode ctx e with_type);
-		List.iter (fun f -> f ()) (List.rev com.callbacks#get_before_typer_create);
+		com.callbacks#run com.error_ext com.callbacks#get_before_typer_create;
 		(* Native lib pass 1: Register *)
 		(* Native lib pass 1: Register *)
-		let fl = List.map (fun (file,extern) -> NativeLibraryHandler.add_native_lib com file extern) (List.rev native_libs) in
+		let fl = List.map (fun lib -> NativeLibraryHandler.add_native_lib com lib) (List.rev native_libs) in
 		(* Native lib pass 2: Initialize *)
 		(* Native lib pass 2: Initialize *)
 		List.iter (fun f -> f()) fl;
 		List.iter (fun f -> f()) fl;
-		Typer.create com
+		TyperEntry.create com macros
 
 
 	let executable_path() =
 	let executable_path() =
 		Extc.executable_path()
 		Extc.executable_path()
@@ -188,18 +205,14 @@ module Setup = struct
 				let share_path = Filename.concat prefix_path "share" in
 				let share_path = Filename.concat prefix_path "share" in
 				[
 				[
 					"";
 					"";
-					Path.add_trailing_slash (Filename.concat lib_path "haxe/std");
-					Path.add_trailing_slash (Filename.concat lib_path "haxe/extraLibs");
 					Path.add_trailing_slash (Filename.concat share_path "haxe/std");
 					Path.add_trailing_slash (Filename.concat share_path "haxe/std");
-					Path.add_trailing_slash (Filename.concat share_path "haxe/extraLibs");
+					Path.add_trailing_slash (Filename.concat lib_path "haxe/std");
 					Path.add_trailing_slash (Filename.concat base_path "std");
 					Path.add_trailing_slash (Filename.concat base_path "std");
-					Path.add_trailing_slash (Filename.concat base_path "extraLibs")
 				]
 				]
 			else
 			else
 				[
 				[
 					"";
 					"";
 					Path.add_trailing_slash (Filename.concat base_path "std");
 					Path.add_trailing_slash (Filename.concat base_path "std");
-					Path.add_trailing_slash (Filename.concat base_path "extraLibs")
 				]
 				]
 
 
 	let setup_common_context ctx =
 	let setup_common_context ctx =
@@ -211,8 +224,10 @@ module Setup = struct
 		Common.define_value com Define.Haxe s_version;
 		Common.define_value com Define.Haxe s_version;
 		Common.raw_define com "true";
 		Common.raw_define com "true";
 		Common.define_value com Define.Dce "std";
 		Common.define_value com Define.Dce "std";
-		com.info <- (fun ?(depth=0) msg p -> message ctx (make_compiler_message msg p depth DKCompilerMessage Information));
-		com.warning <- (fun ?(depth=0) w options msg p ->
+		com.info <- (fun ?(depth=0) ?(from_macro=false) msg p ->
+			message ctx (make_compiler_message ~from_macro msg p depth DKCompilerMessage Information)
+		);
+		com.warning <- (fun ?(depth=0) ?(from_macro=false) w options msg p ->
 			match Warning.get_mode w (com.warning_options @ options) with
 			match Warning.get_mode w (com.warning_options @ options) with
 			| WMEnable ->
 			| WMEnable ->
 				let wobj = Warning.warning_obj w in
 				let wobj = Warning.warning_obj w in
@@ -221,11 +236,12 @@ module Setup = struct
 				else
 				else
 					Printf.sprintf "(%s) %s" wobj.w_name msg
 					Printf.sprintf "(%s) %s" wobj.w_name msg
 				in
 				in
-				message ctx (make_compiler_message msg p depth DKCompilerMessage Warning)
+				message ctx (make_compiler_message ~from_macro msg p depth DKCompilerMessage Warning)
 			| WMDisable ->
 			| WMDisable ->
 				()
 				()
 		);
 		);
-		com.error <- error ctx;
+		com.error_ext <- error_ext ctx;
+		com.error <- (fun ?(depth = 0) msg p -> com.error_ext (Error.make_error ~depth (Custom msg) p));
 		let filter_messages = (fun keep_errors predicate -> (List.filter (fun cm ->
 		let filter_messages = (fun keep_errors predicate -> (List.filter (fun cm ->
 			(match cm.cm_severity with
 			(match cm.cm_severity with
 			| MessageSeverity.Error -> keep_errors;
 			| MessageSeverity.Error -> keep_errors;
@@ -243,83 +259,128 @@ module Setup = struct
 
 
 end
 end
 
 
+let check_defines com =
+	if is_next com then begin
+		PMap.iter (fun k _ ->
+			try
+				let reason = Hashtbl.find Define.deprecation_lut k in
+				let p = { pfile = "-D " ^ k; pmin = -1; pmax = -1 } in
+				com.warning WDeprecatedDefine [] reason p
+			with Not_found ->
+				()
+		) com.defines.values
+	end
+
 (** Creates the typer context and types [classes] into it. *)
 (** Creates the typer context and types [classes] into it. *)
-let do_type ctx tctx actx =
-	let com = tctx.Typecore.com in
+let do_type ctx mctx actx display_file_dot_path macro_cache_enabled =
+	let com = ctx.com in
 	let t = Timer.timer ["typing"] in
 	let t = Timer.timer ["typing"] in
 	let cs = com.cs in
 	let cs = com.cs in
 	CommonCache.maybe_add_context_sign cs com "before_init_macros";
 	CommonCache.maybe_add_context_sign cs com "before_init_macros";
-	com.stage <- CInitMacrosStart;
-	List.iter (MacroContext.call_init_macro tctx) (List.rev actx.config_macros);
-	com.stage <- CInitMacrosDone;
+	enter_stage com CInitMacrosStart;
+	ServerMessage.compiler_stage com;
+
+	let mctx = List.fold_left (fun mctx path ->
+		Some (MacroContext.call_init_macro ctx.com mctx path)
+	) mctx (List.rev actx.config_macros) in
+	enter_stage com CInitMacrosDone;
+	ServerMessage.compiler_stage com;
+	MacroContext.macro_enable_cache := macro_cache_enabled;
+
+	let macros = match mctx with None -> None | Some mctx -> mctx.g.macros in
+	let tctx = Setup.create_typer_context ctx macros actx.native_libs in
+	let display_file_dot_path = DisplayProcessing.maybe_load_display_file_before_typing tctx display_file_dot_path in
+	check_defines ctx.com;
 	CommonCache.lock_signature com "after_init_macros";
 	CommonCache.lock_signature com "after_init_macros";
-	List.iter (fun f -> f ()) (List.rev com.callbacks#get_after_init_macros);
-	run_or_diagnose ctx (fun () ->
-		if com.display.dms_kind <> DMNone then DisplayTexpr.check_display_file tctx cs;
-		List.iter (fun cpath -> ignore(tctx.Typecore.g.Typecore.do_load_module tctx cpath null_pos)) (List.rev actx.classes);
-		Finalization.finalize tctx;
-	) ();
-	com.stage <- CTypingDone;
+	Option.may (fun mctx -> MacroContext.finalize_macro_api tctx mctx) mctx;
+	(try begin
+		com.callbacks#run com.error_ext com.callbacks#get_after_init_macros;
+		run_or_diagnose ctx (fun () ->
+			if com.display.dms_kind <> DMNone then DisplayTexpr.check_display_file tctx cs;
+			List.iter (fun cpath -> ignore(tctx.Typecore.g.Typecore.do_load_module tctx cpath null_pos)) (List.rev actx.classes);
+			Finalization.finalize tctx;
+		);
+	end with TypeloadParse.DisplayInMacroBlock ->
+		ignore(DisplayProcessing.load_display_module_in_macro tctx display_file_dot_path true)
+	);
+	enter_stage com CTypingDone;
+	ServerMessage.compiler_stage com;
 	(* If we are trying to find references, let's syntax-explore everything we know to check for the
 	(* If we are trying to find references, let's syntax-explore everything we know to check for the
 		identifier we are interested in. We then type only those modules that contain the identifier. *)
 		identifier we are interested in. We then type only those modules that contain the identifier. *)
 	begin match com.display.dms_kind with
 	begin match com.display.dms_kind with
 		| (DMUsage _ | DMImplementation) -> FindReferences.find_possible_references tctx cs;
 		| (DMUsage _ | DMImplementation) -> FindReferences.find_possible_references tctx cs;
 		| _ -> ()
 		| _ -> ()
 	end;
 	end;
-	t()
+	t();
+	(tctx, display_file_dot_path)
 
 
 let finalize_typing ctx tctx =
 let finalize_typing ctx tctx =
 	let t = Timer.timer ["finalize"] in
 	let t = Timer.timer ["finalize"] in
 	let com = ctx.com in
 	let com = ctx.com in
-	com.stage <- CFilteringStart;
-	let main, types, modules = run_or_diagnose ctx Finalization.generate tctx in
+	enter_stage com CFilteringStart;
+	ServerMessage.compiler_stage com;
+	let main, types, modules = run_or_diagnose ctx (fun () -> Finalization.generate tctx) in
 	com.main <- main;
 	com.main <- main;
 	com.types <- types;
 	com.types <- types;
 	com.modules <- modules;
 	com.modules <- modules;
 	t()
 	t()
 
 
-let filter ctx tctx =
+let filter ctx tctx before_destruction =
 	let t = Timer.timer ["filters"] in
 	let t = Timer.timer ["filters"] in
 	DeprecationCheck.run ctx.com;
 	DeprecationCheck.run ctx.com;
-	Filters.run ctx.com tctx ctx.com.main;
+	run_or_diagnose ctx (fun () -> Filters.run tctx ctx.com.main before_destruction);
 	t()
 	t()
 
 
-let compile ctx actx =
+let compile ctx actx callbacks =
 	let com = ctx.com in
 	let com = ctx.com in
 	(* Set up display configuration *)
 	(* Set up display configuration *)
 	DisplayProcessing.process_display_configuration ctx;
 	DisplayProcessing.process_display_configuration ctx;
 	let display_file_dot_path = DisplayProcessing.process_display_file com actx in
 	let display_file_dot_path = DisplayProcessing.process_display_file com actx in
+	let macro_cache_enabled = !MacroContext.macro_enable_cache in
+	MacroContext.macro_enable_cache := true;
+	let mctx = match com.platform with
+		| CustomTarget name ->
+			begin try
+				Some (MacroContext.call_init_macro com None (Printf.sprintf "%s.Init.init()" name))
+			with (Error.Error { err_message = Module_not_found ([pack],"Init") }) when pack = name ->
+				(* ignore if <target_name>.Init doesn't exist *)
+				None
+			end
+		| _ ->
+			None
+		in
 	(* Initialize target: This allows access to the appropriate std packages and sets the -D defines. *)
 	(* Initialize target: This allows access to the appropriate std packages and sets the -D defines. *)
 	let ext = Setup.initialize_target ctx com actx in
 	let ext = Setup.initialize_target ctx com actx in
-	com.config <- get_config com; (* make sure to adapt all flags changes defined after platform *)
+	update_platform_config com; (* make sure to adapt all flags changes defined after platform *)
+	callbacks.after_target_init ctx;
 	let t = Timer.timer ["init"] in
 	let t = Timer.timer ["init"] in
 	List.iter (fun f -> f()) (List.rev (actx.pre_compilation));
 	List.iter (fun f -> f()) (List.rev (actx.pre_compilation));
 	t();
 	t();
-	com.stage <- CInitialized;
+	enter_stage com CInitialized;
+	ServerMessage.compiler_stage com;
 	if actx.classes = [([],"Std")] && not actx.force_typing then begin
 	if actx.classes = [([],"Std")] && not actx.force_typing then begin
 		if actx.cmds = [] && not actx.did_something then actx.raise_usage();
 		if actx.cmds = [] && not actx.did_something then actx.raise_usage();
 	end else begin
 	end else begin
 		(* Actual compilation starts here *)
 		(* Actual compilation starts here *)
-		let tctx = Setup.create_typer_context ctx actx.native_libs in
-		com.stage <- CTyperCreated;
-		let display_file_dot_path = DisplayProcessing.maybe_load_display_file_before_typing tctx display_file_dot_path in
-		begin try
-			do_type ctx tctx actx
-		with TypeloadParse.DisplayInMacroBlock ->
-			ignore(DisplayProcessing.load_display_module_in_macro tctx display_file_dot_path true);
-		end;
+		let (tctx,display_file_dot_path) = do_type ctx mctx actx display_file_dot_path macro_cache_enabled in
 		DisplayProcessing.handle_display_after_typing ctx tctx display_file_dot_path;
 		DisplayProcessing.handle_display_after_typing ctx tctx display_file_dot_path;
 		finalize_typing ctx tctx;
 		finalize_typing ctx tctx;
-		DisplayProcessing.handle_display_after_finalization ctx tctx display_file_dot_path;
-		filter ctx tctx;
+		if is_diagnostics com then
+			filter ctx tctx (fun () -> DisplayProcessing.handle_display_after_finalization ctx tctx display_file_dot_path)
+		else begin
+			DisplayProcessing.handle_display_after_finalization ctx tctx display_file_dot_path;
+			filter ctx tctx (fun () -> ());
+		end;
 		if ctx.has_error then raise Abort;
 		if ctx.has_error then raise Abort;
 		Generate.check_auxiliary_output com actx;
 		Generate.check_auxiliary_output com actx;
-		com.stage <- CGenerationStart;
+		enter_stage com CGenerationStart;
+		ServerMessage.compiler_stage com;
 		if not actx.no_output then Generate.generate ctx tctx ext actx;
 		if not actx.no_output then Generate.generate ctx tctx ext actx;
-		com.stage <- CGenerationDone;
+		enter_stage com CGenerationDone;
+		ServerMessage.compiler_stage com;
 	end;
 	end;
 	Sys.catch_break false;
 	Sys.catch_break false;
-	List.iter (fun f -> f()) (List.rev com.callbacks#get_after_generation);
+	com.callbacks#run com.error_ext com.callbacks#get_after_generation;
 	if not actx.no_output then begin
 	if not actx.no_output then begin
 		List.iter (fun c ->
 		List.iter (fun c ->
 			let r = run_command ctx c in
 			let r = run_command ctx c in
@@ -334,10 +395,8 @@ try
 with
 with
 	| Abort ->
 	| Abort ->
 		()
 		()
-	| Error.Fatal_error (m,depth) ->
-		located_error ~depth ctx m
-	| Common.Abort (m,p) ->
-		error ctx m p
+	| Error.Fatal_error err ->
+		error_ext ctx err
 	| Lexer.Error (m,p) ->
 	| Lexer.Error (m,p) ->
 		error ctx (Lexer.error_msg m) p
 		error ctx (Lexer.error_msg m) p
 	| Parser.Error (m,p) ->
 	| Parser.Error (m,p) ->
@@ -350,16 +409,8 @@ with
 			error ctx (Printf.sprintf "You cannot access the %s package while %s (for %s)" pack (if pf = "macro" then "in a macro" else "targeting " ^ pf) (s_type_path m) ) p;
 			error ctx (Printf.sprintf "You cannot access the %s package while %s (for %s)" pack (if pf = "macro" then "in a macro" else "targeting " ^ pf) (s_type_path m) ) p;
 			List.iter (error ~depth:1 ctx (Error.compl_msg "referenced here")) (List.rev pl);
 			List.iter (error ~depth:1 ctx (Error.compl_msg "referenced here")) (List.rev pl);
 		end
 		end
-	| Error.Error (Stack stack,_,depth) -> (match stack with
-		| [] -> ()
-		| (e,p) :: stack -> begin
-			located_error ~depth ctx (Error.error_msg p e);
-			List.iter (fun (e,p) -> located_error ~depth:(depth+1) ctx (Error.error_msg p e)) stack;
-		end)
-	| Error.Error (m,p,depth) ->
-		located_error ~depth ctx (Error.error_msg p m)
-	| Generic.Generic_Exception(m,p) ->
-		error ctx m p
+	| Error.Error err ->
+		error_ext ctx err
 	| Arg.Bad msg ->
 	| Arg.Bad msg ->
 		error ctx ("Error: " ^ msg) null_pos
 		error ctx ("Error: " ^ msg) null_pos
 	| Failure msg when not Helper.is_debug_run ->
 	| Failure msg when not Helper.is_debug_run ->
@@ -373,7 +424,7 @@ with
 		error ctx ("Error: No completion point was found") null_pos
 		error ctx ("Error: No completion point was found") null_pos
 	| DisplayException.DisplayException dex ->
 	| DisplayException.DisplayException dex ->
 		DisplayOutput.handle_display_exception ctx dex
 		DisplayOutput.handle_display_exception ctx dex
-	| Out_of_memory | EvalExceptions.Sys_exit _ | Hlinterp.Sys_exit _ | DisplayProcessingGlobals.Completion _ as exc ->
+	| Out_of_memory | EvalTypes.Sys_exit _ | Hlinterp.Sys_exit _ | DisplayProcessingGlobals.Completion _ as exc ->
 		(* We don't want these to be caught by the catchall below *)
 		(* We don't want these to be caught by the catchall below *)
 		raise exc
 		raise exc
 	| e when (try Sys.getenv "OCAMLRUNPARAM" <> "b" with _ -> true) && not Helper.is_debug_run ->
 	| e when (try Sys.getenv "OCAMLRUNPARAM" <> "b" with _ -> true) && not Helper.is_debug_run ->
@@ -399,7 +450,7 @@ let catch_completion_and_exit ctx callbacks run =
 			ServerMessage.completion str;
 			ServerMessage.completion str;
 			ctx.comm.write_err str;
 			ctx.comm.write_err str;
 			0
 			0
-		| EvalExceptions.Sys_exit i | Hlinterp.Sys_exit i ->
+		| EvalTypes.Sys_exit i | Hlinterp.Sys_exit i ->
 			if i <> 0 then ctx.has_error <- true;
 			if i <> 0 then ctx.has_error <- true;
 			finalize ctx;
 			finalize ctx;
 			i
 			i
@@ -408,7 +459,10 @@ let process_actx ctx actx =
 	DisplayProcessing.process_display_arg ctx actx;
 	DisplayProcessing.process_display_arg ctx actx;
 	List.iter (fun s ->
 	List.iter (fun s ->
 		ctx.com.warning WDeprecated [] s null_pos
 		ctx.com.warning WDeprecated [] s null_pos
-	) actx.deprecations
+	) actx.deprecations;
+	if defined ctx.com NoDeprecationWarnings then begin
+		ctx.com.warning_options <- [{wo_warning = WDeprecated; wo_mode = WMDisable}] :: ctx.com.warning_options
+	end
 
 
 let compile_ctx callbacks ctx =
 let compile_ctx callbacks ctx =
 	let run ctx =
 	let run ctx =
@@ -417,8 +471,7 @@ let compile_ctx callbacks ctx =
 		compile_safe ctx (fun () ->
 		compile_safe ctx (fun () ->
 			let actx = Args.parse_args ctx.com in
 			let actx = Args.parse_args ctx.com in
 			process_actx ctx actx;
 			process_actx ctx actx;
-			callbacks.after_arg_parsing ctx;
-			compile ctx actx;
+			compile ctx actx callbacks;
 		);
 		);
 		finalize ctx;
 		finalize ctx;
 		callbacks.after_compilation ctx;
 		callbacks.after_compilation ctx;
@@ -430,7 +483,7 @@ let compile_ctx callbacks ctx =
 		catch_completion_and_exit ctx callbacks run
 		catch_completion_and_exit ctx callbacks run
 
 
 let create_context comm cs compilation_step params = {
 let create_context comm cs compilation_step params = {
-	com = Common.create compilation_step cs version params;
+	com = Common.create compilation_step cs version params (DisplayTypes.DisplayMode.create !Parser.display_mode);
 	messages = [];
 	messages = [];
 	has_next = false;
 	has_next = false;
 	has_error = false;
 	has_error = false;
@@ -481,7 +534,7 @@ module HighLevel = struct
 					"-cp" :: l :: acc
 					"-cp" :: l :: acc
 				else match (try ExtString.String.split l " " with _ -> l, "") with
 				else match (try ExtString.String.split l " " with _ -> l, "") with
 				| ("-L",dir) ->
 				| ("-L",dir) ->
-					"--neko-lib" :: (String.sub l 3 (String.length l - 3)) :: acc
+					"--neko-lib-path" :: (String.sub l 3 (String.length l - 3)) :: acc
 				| param, value ->
 				| param, value ->
 					let acc = if value <> "" then value :: acc else acc in
 					let acc = if value <> "" then value :: acc else acc in
 					let acc = param :: acc in
 					let acc = param :: acc in
@@ -490,14 +543,13 @@ module HighLevel = struct
 			lines
 			lines
 
 
 	(* Returns a list of contexts, but doesn't do anything yet *)
 	(* Returns a list of contexts, but doesn't do anything yet *)
-	let process_params server_api create each_params has_display is_server pl =
-		let curdir = Unix.getcwd () in
+	let process_params server_api create each_args has_display is_server args =
+		(* We want the loop below to actually see all the --each params, so let's prepend them *)
+		let args = !each_args @ args in
 		let added_libs = Hashtbl.create 0 in
 		let added_libs = Hashtbl.create 0 in
 		let server_mode = ref SMNone in
 		let server_mode = ref SMNone in
 		let create_context args =
 		let create_context args =
 			let ctx = create (server_api.on_context_create()) args in
 			let ctx = create (server_api.on_context_create()) args in
-			(* --cwd triggers immediately, so let's reset *)
-			Unix.chdir curdir;
 			ctx
 			ctx
 		in
 		in
 		let rec find_subsequent_libs acc args = match args with
 		let rec find_subsequent_libs acc args = match args with
@@ -508,16 +560,16 @@ module HighLevel = struct
 		in
 		in
 		let rec loop acc = function
 		let rec loop acc = function
 			| [] ->
 			| [] ->
-				[],Some (create_context (!each_params @ (List.rev acc)))
+				[],Some (create_context (List.rev acc))
 			| "--next" :: l when acc = [] -> (* skip empty --next *)
 			| "--next" :: l when acc = [] -> (* skip empty --next *)
 				loop [] l
 				loop [] l
 			| "--next" :: l ->
 			| "--next" :: l ->
-				let ctx = create_context (!each_params @ (List.rev acc)) in
+				let ctx = create_context (List.rev acc) in
 				ctx.has_next <- true;
 				ctx.has_next <- true;
 				l,Some ctx
 				l,Some ctx
 			| "--each" :: l ->
 			| "--each" :: l ->
-				each_params := List.rev acc;
-				loop [] l
+				each_args := List.rev acc;
+				loop acc l
 			| "--cwd" :: dir :: l | "-C" :: dir :: l ->
 			| "--cwd" :: dir :: l | "-C" :: dir :: l ->
 				(* we need to change it immediately since it will affect hxml loading *)
 				(* we need to change it immediately since it will affect hxml loading *)
 				(try Unix.chdir dir with _ -> raise (Arg.Bad ("Invalid directory: " ^ dir)));
 				(try Unix.chdir dir with _ -> raise (Arg.Bad ("Invalid directory: " ^ dir)));
@@ -528,8 +580,8 @@ module HighLevel = struct
 					(* If we are already connected, ignore (issue #10813) *)
 					(* If we are already connected, ignore (issue #10813) *)
 					loop acc l
 					loop acc l
 				else begin
 				else begin
-					let host, port = (try ExtString.String.split hp ":" with _ -> "127.0.0.1", hp) in
-					server_api.do_connect host (try int_of_string port with _ -> raise (Arg.Bad "Invalid port")) ((List.rev acc) @ l);
+					let host, port = Helper.parse_host_port hp in
+					server_api.do_connect host port ((List.rev acc) @ l);
 					[],None
 					[],None
 				end
 				end
 			| "--server-connect" :: hp :: l ->
 			| "--server-connect" :: hp :: l ->
@@ -540,14 +592,14 @@ module HighLevel = struct
 				loop acc l
 				loop acc l
 			| "--run" :: cl :: args ->
 			| "--run" :: cl :: args ->
 				let acc = cl :: "-x" :: acc in
 				let acc = cl :: "-x" :: acc in
-				let ctx = create_context (!each_params @ (List.rev acc)) in
+				let ctx = create_context (List.rev acc) in
 				ctx.com.sys_args <- args;
 				ctx.com.sys_args <- args;
 				[],Some ctx
 				[],Some ctx
 			| ("-L" | "--library" | "-lib") :: name :: args ->
 			| ("-L" | "--library" | "-lib") :: name :: args ->
 				let libs,args = find_subsequent_libs [name] args in
 				let libs,args = find_subsequent_libs [name] args in
 				let libs = List.filter (fun l -> not (Hashtbl.mem added_libs l)) libs in
 				let libs = List.filter (fun l -> not (Hashtbl.mem added_libs l)) libs in
 				List.iter (fun l -> Hashtbl.add added_libs l ()) libs;
 				List.iter (fun l -> Hashtbl.add added_libs l ()) libs;
-				let lines = add_libs libs pl server_api.cache has_display in
+				let lines = add_libs libs args server_api.cache has_display in
 				loop acc (lines @ args)
 				loop acc (lines @ args)
 			| ("--jvm" | "--java" | "-java" as arg) :: dir :: args ->
 			| ("--jvm" | "--java" | "-java" as arg) :: dir :: args ->
 				loop_lib arg dir "hxjava" acc args
 				loop_lib arg dir "hxjava" acc args
@@ -563,7 +615,7 @@ module HighLevel = struct
 		and loop_lib arg dir lib acc args =
 		and loop_lib arg dir lib acc args =
 			loop (dir :: arg :: acc) ("-lib" :: lib :: args)
 			loop (dir :: arg :: acc) ("-lib" :: lib :: args)
 		in
 		in
-		let args,ctx = loop [] pl in
+		let args,ctx = loop [] args in
 		args,!server_mode,ctx
 		args,!server_mode,ctx
 
 
 	let execute_ctx server_api ctx server_mode =
 	let execute_ctx server_api ctx server_mode =
@@ -591,6 +643,7 @@ module HighLevel = struct
 	let entry server_api comm args =
 	let entry server_api comm args =
 		let create = create_context comm server_api.cache in
 		let create = create_context comm server_api.cache in
 		let each_args = ref [] in
 		let each_args = ref [] in
+		let curdir = Unix.getcwd () in
 		let has_display = ref false in
 		let has_display = ref false in
 		(* put --display in front if it was last parameter *)
 		(* put --display in front if it was last parameter *)
 		let args = match List.rev args with
 		let args = match List.rev args with
@@ -610,14 +663,18 @@ module HighLevel = struct
 			in
 			in
 			let code = match ctx with
 			let code = match ctx with
 				| Some ctx ->
 				| Some ctx ->
+					(* Need chdir here because --cwd is eagerly applied in process_params *)
+					Unix.chdir curdir;
 					execute_ctx server_api ctx server_mode
 					execute_ctx server_api ctx server_mode
 				| None ->
 				| None ->
 					(* caused by --connect *)
 					(* caused by --connect *)
 					0
 					0
 			in
 			in
-			if code = 0 && args <> [] then
+			if code = 0 && args <> [] && not !has_display then begin
+				(* We have to chdir here again because any --cwd also takes effect in execute_ctx *)
+				Unix.chdir curdir;
 				loop args
 				loop args
-			else
+			end else
 				code
 				code
 		in
 		in
 		let code = loop args in
 		let code = loop args in

+ 18 - 12
src/compiler/displayOutput.ml

@@ -1,20 +1,16 @@
 open Globals
 open Globals
 open Ast
 open Ast
 open Common
 open Common
-open Filename
 open Timer
 open Timer
 open DisplayTypes.DisplayMode
 open DisplayTypes.DisplayMode
 open DisplayTypes.CompletionResultKind
 open DisplayTypes.CompletionResultKind
 open CompletionItem
 open CompletionItem
 open CompletionClassField
 open CompletionClassField
 open CompletionEnumField
 open CompletionEnumField
-open ClassFieldOrigin
 open DisplayException
 open DisplayException
 open Type
 open Type
-open Display
 open DisplayTypes
 open DisplayTypes
 open CompletionModuleType
 open CompletionModuleType
-open Typecore
 open Genjson
 open Genjson
 open CompilationContext
 open CompilationContext
 open DisplayProcessingGlobals
 open DisplayProcessingGlobals
@@ -71,8 +67,8 @@ let print_fields fields =
 		| ITPackage(path,_) -> "package",snd path,"",None
 		| ITPackage(path,_) -> "package",snd path,"",None
 		| ITModule path -> "type",snd path,"",None
 		| ITModule path -> "type",snd path,"",None
 		| ITMetadata  meta ->
 		| ITMetadata  meta ->
-			let s,(doc,_),_ = Meta.get_info meta in
-			"metadata","@" ^ s,"",doc_from_string doc
+			let s,data  = Meta.get_info meta in
+			"metadata","@" ^ s,"",doc_from_string data.m_doc
 		| ITTimer(name,value) -> "timer",name,"",doc_from_string value
 		| ITTimer(name,value) -> "timer",name,"",doc_from_string value
 		| ITLiteral s ->
 		| ITLiteral s ->
 			let t = match k.ci_type with None -> t_dynamic | Some (t,_) -> t in
 			let t = match k.ci_type with None -> t_dynamic | Some (t,_) -> t in
@@ -213,7 +209,7 @@ let find_doc t =
 	let doc = match follow t with
 	let doc = match follow t with
 		| TAnon an ->
 		| TAnon an ->
 			begin match !(an.a_status) with
 			begin match !(an.a_status) with
-				| Statics c -> c.cl_doc
+				| ClassStatics c -> c.cl_doc
 				| EnumStatics en -> en.e_doc
 				| EnumStatics en -> en.e_doc
 				| AbstractStatics a -> a.a_doc
 				| AbstractStatics a -> a.a_doc
 				| _ -> None
 				| _ -> None
@@ -348,10 +344,10 @@ let handle_type_path_exception ctx p c is_import pos =
 			| None ->
 			| None ->
 				DisplayPath.TypePathHandler.complete_type_path com p
 				DisplayPath.TypePathHandler.complete_type_path com p
 			| Some (c,cur_package) ->
 			| Some (c,cur_package) ->
-				let ctx = Typer.create com in
+				let ctx = TyperEntry.create com None in
 				DisplayPath.TypePathHandler.complete_type_path_inner ctx p c cur_package is_import
 				DisplayPath.TypePathHandler.complete_type_path_inner ctx p c cur_package is_import
-		end with Common.Abort(msg,p) ->
-			error ctx msg p;
+		end with Error.Fatal_error err ->
+			error_ext ctx err;
 			None
 			None
 	in
 	in
 	begin match ctx.com.json_out,fields with
 	begin match ctx.com.json_out,fields with
@@ -372,13 +368,23 @@ let handle_type_path_exception ctx p c is_import pos =
 		api.send_result (DisplayException.fields_to_json ctx fields kind (DisplayTypes.make_subject None pos));
 		api.send_result (DisplayException.fields_to_json ctx fields kind (DisplayTypes.make_subject None pos));
 	end
 	end
 
 
-let emit_diagnostics com =
+let emit_legacy_diagnostics com =
 	let dctx = Diagnostics.run com in
 	let dctx = Diagnostics.run com in
 	let s = Json.string_of_json (DiagnosticsPrinter.json_of_diagnostics com dctx) in
 	let s = Json.string_of_json (DiagnosticsPrinter.json_of_diagnostics com dctx) in
 	DisplayPosition.display_position#reset;
 	DisplayPosition.display_position#reset;
 	raise (Completion s)
 	raise (Completion s)
 
 
+let emit_diagnostics com =
+	(match com.Common.json_out with
+	| None -> die "" __LOC__
+	| Some api ->
+		let dctx = Diagnostics.run com in
+		let diagnostics = DiagnosticsPrinter.json_of_diagnostics com dctx in
+		DisplayPosition.display_position#reset;
+		api.send_result diagnostics;
+		raise Abort (* not reached because send_result always raises *))
+
 let emit_statistics tctx =
 let emit_statistics tctx =
 	let stats = Statistics.collect_statistics tctx [SFFile (DisplayPosition.display_position#get).pfile] true in
 	let stats = Statistics.collect_statistics tctx [SFFile (DisplayPosition.display_position#get).pfile] true in
 	let s = Statistics.Printer.print_statistics stats in
 	let s = Statistics.Printer.print_statistics stats in
-	raise (Completion s)
+	raise (Completion s)

+ 20 - 18
src/compiler/displayProcessing.ml

@@ -22,7 +22,7 @@ let handle_display_argument_old com file_pos actx =
 		actx.did_something <- true;
 		actx.did_something <- true;
 		(try Memory.display_memory com with e -> prerr_endline (Printexc.get_backtrace ()));
 		(try Memory.display_memory com with e -> prerr_endline (Printexc.get_backtrace ()));
 	| "diagnostics" ->
 	| "diagnostics" ->
-		com.report_mode <- RMDiagnostics []
+		com.report_mode <- RMLegacyDiagnostics []
 	| _ ->
 	| _ ->
 		let file, pos = try ExtString.String.split file_pos "@" with _ -> failwith ("Invalid format: " ^ file_pos) in
 		let file, pos = try ExtString.String.split file_pos "@" with _ -> failwith ("Invalid format: " ^ file_pos) in
 		let file = Helper.unquote file in
 		let file = Helper.unquote file in
@@ -46,9 +46,9 @@ let handle_display_argument_old com file_pos actx =
 			| "module-symbols" ->
 			| "module-symbols" ->
 				create (DMModuleSymbols None)
 				create (DMModuleSymbols None)
 			| "diagnostics" ->
 			| "diagnostics" ->
-				com.report_mode <- RMDiagnostics [file_unique];
+				com.report_mode <- RMLegacyDiagnostics [file_unique];
 				let dm = create DMNone in
 				let dm = create DMNone in
-				{dm with dms_display_file_policy = DFPAlso; dms_per_file = true}
+				{dm with dms_display_file_policy = DFPOnly; dms_per_file = true; dms_populate_cache = !ServerConfig.populate_cache_from_display}
 			| "statistics" ->
 			| "statistics" ->
 				com.report_mode <- RMStatistics;
 				com.report_mode <- RMStatistics;
 				let dm = create DMNone in
 				let dm = create DMNone in
@@ -92,13 +92,14 @@ let process_display_arg ctx actx =
 let process_display_configuration ctx =
 let process_display_configuration ctx =
 	let com = ctx.com in
 	let com = ctx.com in
 	if is_diagnostics com then begin
 	if is_diagnostics com then begin
-		com.info <- (fun ?depth s p ->
-			add_diagnostics_message com (located s p) DKCompilerMessage Information
+		com.info <- (fun ?depth ?from_macro s p ->
+			add_diagnostics_message ?depth com s p DKCompilerMessage Information
 		);
 		);
-		com.warning <- (fun ?depth w options s p ->
+		com.warning <- (fun ?(depth = 0) ?from_macro w options s p ->
 			match Warning.get_mode w (com.warning_options @ options) with
 			match Warning.get_mode w (com.warning_options @ options) with
 			| WMEnable ->
 			| WMEnable ->
-				add_diagnostics_message com (located s p) DKCompilerMessage Warning
+				let wobj = Warning.warning_obj w in
+				add_diagnostics_message ~depth ~code:(Some wobj.w_name) com s p DKCompilerMessage Warning
 			| WMDisable ->
 			| WMDisable ->
 				()
 				()
 		);
 		);
@@ -142,11 +143,11 @@ let process_display_file com actx =
 		| DFPOnly when (DisplayPosition.display_position#get).pfile = file_input_marker ->
 		| DFPOnly when (DisplayPosition.display_position#get).pfile = file_input_marker ->
 			actx.classes <- [];
 			actx.classes <- [];
 			com.main_class <- None;
 			com.main_class <- None;
-			begin match !TypeloadParse.current_stdin with
-			| Some input ->
-				TypeloadParse.current_stdin := None;
+			begin match com.file_contents with
+			| [_, Some input] ->
+				com.file_contents <- [];
 				DPKInput input
 				DPKInput input
-			| None ->
+			| _ ->
 				DPKNone
 				DPKNone
 			end
 			end
 		| dfp ->
 		| dfp ->
@@ -192,24 +193,24 @@ let load_display_module_in_macro tctx display_file_dot_path clear = match displa
 		let p = null_pos in
 		let p = null_pos in
 		begin try
 		begin try
 			let open Typecore in
 			let open Typecore in
-			let _, mctx = MacroContext.get_macro_context tctx p in
+			let mctx = MacroContext.get_macro_context tctx in
 			(* Tricky stuff: We want to remove the module from our lookups and load it again in
 			(* Tricky stuff: We want to remove the module from our lookups and load it again in
 				display mode. This covers some cases like --macro typing it in non-display mode (issue #7017). *)
 				display mode. This covers some cases like --macro typing it in non-display mode (issue #7017). *)
 			if clear then begin
 			if clear then begin
 				begin try
 				begin try
 					let m = mctx.com.module_lut#find cpath in
 					let m = mctx.com.module_lut#find cpath in
 					mctx.com.module_lut#remove cpath;
 					mctx.com.module_lut#remove cpath;
-					mctx.com.type_to_module#remove cpath;
+					mctx.com.module_lut#get_type_lut#remove cpath;
 					List.iter (fun mt ->
 					List.iter (fun mt ->
 						let ti = Type.t_infos mt in
 						let ti = Type.t_infos mt in
 						mctx.com.module_lut#remove ti.mt_path;
 						mctx.com.module_lut#remove ti.mt_path;
-						mctx.com.type_to_module#remove ti.mt_path;
+						mctx.com.module_lut#get_type_lut#remove ti.mt_path;
 					) m.m_types
 					) m.m_types
 				with Not_found ->
 				with Not_found ->
 					()
 					()
 				end;
 				end;
 			end;
 			end;
-			let _ = MacroContext.load_macro_module tctx cpath true p in
+			let _ = MacroContext.load_macro_module (MacroContext.get_macro_context tctx) tctx.com cpath true p in
 			Finalization.finalize mctx;
 			Finalization.finalize mctx;
 			Some mctx
 			Some mctx
 		with DisplayException.DisplayException _ | Parser.TypePath _ as exc ->
 		with DisplayException.DisplayException _ | Parser.TypePath _ as exc ->
@@ -268,7 +269,7 @@ let maybe_load_display_file_before_typing tctx display_file_dot_path = match dis
 
 
 let handle_display_after_typing ctx tctx display_file_dot_path =
 let handle_display_after_typing ctx tctx display_file_dot_path =
 	let com = ctx.com in
 	let com = ctx.com in
-	if ctx.com.display.dms_kind = DMNone & ctx.has_error then raise Abort;
+	if ctx.com.display.dms_kind = DMNone && ctx.has_error then raise Abort;
 	begin match ctx.com.display.dms_kind,!Parser.delayed_syntax_completion with
 	begin match ctx.com.display.dms_kind,!Parser.delayed_syntax_completion with
 		| DMDefault,Some(kind,subj) -> DisplayOutput.handle_syntax_completion com kind subj
 		| DMDefault,Some(kind,subj) -> DisplayOutput.handle_syntax_completion com kind subj
 		| _ -> ()
 		| _ -> ()
@@ -311,7 +312,6 @@ let process_global_display_mode com tctx =
 		FindReferences.find_references tctx com with_definition
 		FindReferences.find_references tctx com with_definition
 	| DMImplementation ->
 	| DMImplementation ->
 		FindReferences.find_implementations tctx com
 		FindReferences.find_implementations tctx com
-	| DMModuleSymbols (Some "") -> ()
 	| DMModuleSymbols filter ->
 	| DMModuleSymbols filter ->
 		let open CompilationCache in
 		let open CompilationCache in
 		let cs = com.cs in
 		let cs = com.cs in
@@ -348,10 +348,12 @@ let handle_display_after_finalization ctx tctx display_file_dot_path =
 	end;
 	end;
 	process_global_display_mode com tctx;
 	process_global_display_mode com tctx;
 	begin match com.report_mode with
 	begin match com.report_mode with
+	| RMLegacyDiagnostics _ ->
+		DisplayOutput.emit_legacy_diagnostics com
 	| RMDiagnostics _ ->
 	| RMDiagnostics _ ->
 		DisplayOutput.emit_diagnostics com
 		DisplayOutput.emit_diagnostics com
 	| RMStatistics ->
 	| RMStatistics ->
 		DisplayOutput.emit_statistics tctx
 		DisplayOutput.emit_statistics tctx
 	| RMNone ->
 	| RMNone ->
 		()
 		()
-	end
+	end

+ 11 - 9
src/compiler/generate.ml

@@ -57,8 +57,6 @@ let generate ctx tctx ext actx =
 	end;
 	end;
 	if actx.interp then
 	if actx.interp then
 		Std.finally (Timer.timer ["interp"]) MacroContext.interpret tctx
 		Std.finally (Timer.timer ["interp"]) MacroContext.interpret tctx
-	else if com.platform = Cross then
-		()
 	else begin
 	else begin
 		let generate,name = match com.platform with
 		let generate,name = match com.platform with
 		| Flash ->
 		| Flash ->
@@ -91,11 +89,15 @@ let generate ctx tctx ext actx =
 			Genhl.generate,"hl"
 			Genhl.generate,"hl"
 		| Eval ->
 		| Eval ->
 			(fun _ -> MacroContext.interpret tctx),"eval"
 			(fun _ -> MacroContext.interpret tctx),"eval"
-		| Cross ->
-			die "" __LOC__
+		| Cross
+		| CustomTarget _ ->
+			(fun _ -> ()),""
 		in
 		in
-		Common.log com ("Generating " ^ name ^ ": " ^ com.file);
-		let t = Timer.timer ["generate";name] in
-		generate com;
-		t()
-	end
+		if name = "" then ()
+		else begin
+			Common.log com ("Generating " ^ name ^ ": " ^ com.file);
+			let t = Timer.timer ["generate";name] in
+			generate com;
+			t()
+		end
+	end

+ 14 - 3
src/compiler/helper.ml

@@ -1,3 +1,4 @@
+open Ipaddr
 exception HelpMessage of string
 exception HelpMessage of string
 
 
 let is_debug_run = try Sys.getenv "HAXEDEBUG" = "1" with _ -> false
 let is_debug_run = try Sys.getenv "HAXEDEBUG" = "1" with _ -> false
@@ -52,6 +53,16 @@ let parse_hxml file =
 	parse_hxml_data data
 	parse_hxml_data data
 
 
 let parse_host_port hp =
 let parse_host_port hp =
-	let host, port = (try ExtString.String.split hp ":" with _ -> "127.0.0.1", hp) in
-	let port = try int_of_string port with _ -> raise (Arg.Bad "Invalid port") in
-	host, port
+	match (Ipaddr.with_port_of_string ~default:(-1) hp) with
+	(* Short ipv6 notation will be mixed up with port; extract port and rebuild ipv6 *)
+	| Ok (V6 ip, -1) ->
+		let octets = ExtLib.String.split_on_char ':' (V6.to_string ip) in
+		(match (List.rev octets) with
+			| port :: octets -> (try V6 (V6.of_string_exn (ExtLib.String.join ":" (List.rev octets))), int_of_string port with _ -> raise (Arg.Bad "Invalid host/port"))
+			| _ -> raise (Arg.Bad "Invalid host/port")
+		)
+	| Ok (_, -1) -> raise (Arg.Bad "Invalid host/port: missing port")
+	| Ok (ip, port) -> ip, port
+	(* Default to 127.0.0.1 with given port if no host is provided *)
+	| Error _ when Str.string_match (Str.regexp "[0-9]+$") hp 0 -> V4 (V4.of_string_exn "127.0.0.1"), int_of_string hp
+	| Error _ -> raise (Arg.Bad "Invalid host/port")

+ 401 - 0
src/compiler/messageReporting.ml

@@ -0,0 +1,401 @@
+open Extlib_leftovers
+open Globals
+open Common
+open CompilationContext
+
+let resolve_source file l1 p1 l2 p2 =
+	let ch = open_in_bin file in
+	let curline = ref 1 in
+	let lines = ref [] in
+	let rec loop p line =
+		let inc i line =
+			if (!curline >= l1) && (!curline <= l2) then lines := (!curline, line) :: !lines;
+			curline := !curline + 1;
+			(i, "")
+		in
+
+		let input_char_or_done ch line =
+			try input_char ch with End_of_file -> begin
+				ignore(inc 0 line);
+				raise End_of_file
+			end
+		in
+
+		let read_char line = match input_char_or_done ch line with
+			| '\n' -> inc 1 line
+			| '\r' ->
+				ignore(input_char_or_done ch line);
+				inc 2 line
+			| c -> begin
+				let line = ref (line ^ (String.make 1 c)) in
+				let rec skip n =
+					if n > 0 then begin
+						let c = input_char_or_done ch !line in
+						line := !line ^ (String.make 1 c);
+						skip (n - 1)
+					end
+				in
+
+				let code = int_of_char c in
+				if code < 0xC0 then ()
+				else if code < 0xE0 then skip 1
+				else if code < 0xF0 then skip 2
+				else skip 3;
+
+				(1, !line)
+			end
+		in
+
+		let (delta, line) = read_char line in
+		loop (p + delta) line
+	in
+
+	try loop 0 ""; with End_of_file -> close_in ch;
+	List.rev !lines
+
+let resolve_file ctx f =
+		let ext = Common.extension f in
+		let second_ext = Common.extension (Common.remove_extension f) in
+		let platform_ext = "." ^ (platform_name_macro ctx) in
+		if platform_ext = second_ext then
+			(Common.remove_extension (Common.remove_extension f)) ^ ext
+		else
+			f
+
+let error_printer file line = Printf.sprintf "%s:%d:" file line
+
+type error_context = {
+	absolute_positions : bool;
+	mutable last_positions : pos IntMap.t;
+	mutable max_lines : int IntMap.t;
+	mutable gutter : int IntMap.t;
+	mutable previous : (pos * MessageSeverity.t * int) option;
+}
+
+let create_error_context absolute_positions = {
+	absolute_positions = absolute_positions;
+	last_positions = IntMap.empty;
+	max_lines = IntMap.empty;
+	gutter = IntMap.empty;
+	previous = None;
+}
+
+let compiler_pretty_message_string com ectx cm =
+	match cm.cm_message with
+	(* Filter some messages that don't add much when using this message renderer *)
+	| "End of overload failure reasons" -> None
+	| _ -> begin
+		ectx.last_positions <- (IntMap.add cm.cm_depth cm.cm_pos ectx.last_positions);
+		let is_null_pos = cm.cm_pos = null_pos || cm.cm_pos.pmin = -1 in
+		let is_unknown_file f = f = "" || f = "?" in
+
+		(* Extract informations from position *)
+		let l1, p1, l2, p2, epos, lines =
+			if is_null_pos then begin
+				let epos = if is_unknown_file cm.cm_pos.pfile then "(unknown position)" else cm.cm_pos.pfile in
+				(-1, -1, -1, -1, epos, [])
+			end else try begin
+				let f = resolve_file com cm.cm_pos.pfile in
+				let f = Common.find_file com f in
+				let l1, p1, l2, p2 = Lexer.get_pos_coords cm.cm_pos in
+				let lines = resolve_source f l1 p1 l2 p2 in
+				let epos =
+					if ectx.absolute_positions then TPrinting.Printer.s_pos cm.cm_pos
+					else Lexer.get_error_pos error_printer cm.cm_pos
+				in
+				(l1, p1, l2, p2, epos, lines)
+			end with Not_found | Sys_error _ ->
+				(1, 1, 1, 1, cm.cm_pos.pfile, [])
+			in
+
+		(* If 4 lines or less, display all; if more, crop the middle *)
+		let lines = match lines with
+			| _ :: (_ :: (_ :: (_ :: []))) -> lines
+			| hd :: (_ :: (_ :: (_ :: l))) ->
+				let _,line = hd in
+				let indent = ref 0 in
+				let found = ref false in
+
+				while (not !found) && (!indent < (String.length line - 1)) do
+					found := not (Lexer.is_whitespace (String.unsafe_get line !indent));
+					indent := !indent + 1
+				done;
+
+				[hd; (0, (String.make (!indent+1) ' ') ^ "[...]"); List.hd (List.rev l)]
+			| _ -> lines
+		in
+
+		let parent_pos =
+			if cm.cm_depth = 0 then null_pos
+			else (try IntMap.find (cm.cm_depth-1) ectx.last_positions with Not_found -> null_pos)
+		in
+
+		let prev_pos,prev_sev,prev_nl = match ectx.previous with
+			| None -> (None, None, 0)
+			| Some (p, sev, depth) -> (Some p, Some sev, depth)
+		in
+
+		let sev_changed = prev_sev = None || Some cm.cm_severity <> prev_sev in
+		let pos_changed = (prev_pos = None || cm.cm_pos <> Option.get prev_pos || (cm.cm_depth <> prev_nl && cm.cm_depth <> prev_nl + 1)) && (parent_pos = null_pos || cm.cm_pos <> parent_pos) in
+		let file_changed = prev_pos = None || (pos_changed && match (cm.cm_pos.pfile, (Option.get prev_pos).pfile) with
+			| (f1, f2) when (is_unknown_file f1) && (is_unknown_file f2) -> false
+			| (f1, f2) -> f1 <> f2
+		) in
+
+		let display_heading = cm.cm_depth = 0 || sev_changed || file_changed in
+		let has_source = match lines with | [] -> false | _ -> true in
+		let display_source = has_source && (cm.cm_depth = 0 || sev_changed || pos_changed) in
+		let display_pos_marker = (not is_null_pos) && has_source && (cm.cm_depth = 0 || sev_changed || pos_changed) in
+
+		let gutter_len = (try String.length (Printf.sprintf "%d" (IntMap.find cm.cm_depth ectx.max_lines)) with Not_found -> 0) + 2 in
+
+		let no_color = Define.defined com.defines Define.MessageNoColor in
+		let c_reset = if no_color then "" else "\x1b[0m" in
+		let c_bold = if no_color then "" else "\x1b[1m" in
+		let c_dim = if no_color then "" else "\x1b[2m" in
+
+		let (c_sev, c_sev_bg) = if no_color then ("", "") else match cm.cm_severity with
+			| MessageSeverity.Warning -> ("\x1b[33m", "\x1b[30;43m")
+			| Information | Hint -> ("\x1b[34m", "\x1b[30;44m")
+			| Error -> ("\x1b[31m", "\x1b[30;41m")
+		in
+
+		let sev_label = if cm.cm_depth > 0 then " -> " else Printf.sprintf
+			(if no_color then "[%s]" else " %s ")
+			(match cm.cm_severity with
+				| MessageSeverity.Warning -> "WARNING"
+				| Information -> "INFO"
+				| Hint -> "HINT"
+				| Error -> "ERROR"
+			) in
+
+		let out = ref "" in
+
+		if display_heading then
+			out := Printf.sprintf "%s%s%s\n\n"
+				(* Severity heading *)
+				(c_sev_bg ^ sev_label ^ c_reset ^ " ")
+				(* Macro context indicator *)
+				(if cm.cm_from_macro then c_sev ^ "(macro) " ^ c_reset else "")
+				(* File + line pointer *)
+				epos;
+
+		(* Error source *)
+		if display_source then out := List.fold_left (fun out (l, line) ->
+			let nb_len = String.length (string_of_int l) in
+
+			(* Replace tabs with 1 space to avoid column misalignments *)
+			let line = String.concat " " (ExtString.String.nsplit line "\t") in
+			let len = String.length line in
+
+			out ^ Printf.sprintf "%s%s | %s\n"
+				(* left-padded line number *)
+				(String.make (gutter_len-nb_len-1) ' ')
+				(if l = 0 then "-" else Printf.sprintf "%d" l)
+				(* Source code at that line *)
+				(
+					if l = 0 then
+						c_dim ^ line ^ c_reset
+					else if l1 = l2 then
+						(if p1 > 1 then c_dim ^ (String.sub line 0 (p1-1)) else "")
+						^ c_reset ^ c_bold ^ (String.sub line (p1-1) (p2-p1))
+						^ c_reset ^ c_dim ^ (String.sub line (p2-1) (len - p2 + 1))
+						^ c_reset
+					else begin
+						(if (l = l1) then
+							(if p1 > 1 then c_dim ^ (String.sub line 0 (p1-1)) else "")
+							^ c_reset ^ c_bold ^ (String.sub line (p1-1) (len-p1+1))
+							^ c_reset
+						else if (l = l2) then
+							(if p2 > 1 then c_bold ^ (String.sub line 0 (p2-1)) else "")
+							^ c_reset ^ c_dim ^ (String.sub line (p2-1) (len-p2+1))
+							^ c_reset
+						else c_bold ^ line ^ c_reset)
+					end
+				)
+		) !out lines;
+
+		(* Error position marker *)
+		if display_pos_marker then
+			out := Printf.sprintf "%s%s|%s\n"
+				!out
+				(String.make gutter_len ' ')
+				(if l1 = l2 then String.make p1 ' ' ^ c_sev ^ String.make (if p1 = p2 then 1 else p2-p1) '^' ^ c_reset else "");
+
+		(* Error message *)
+		out := List.fold_left (fun out str -> Printf.sprintf "%s%s| %s\n"
+			out
+			(String.make gutter_len ' ')
+			(* Remove "... " prefix *)
+			(if (ExtString.String.starts_with str "... ") then String.sub str 4 ((String.length str) - 4) else str)
+		) !out (ExtString.String.nsplit cm.cm_message "\n");
+
+		ectx.previous <- Some ((if is_null_pos then null_pos else cm.cm_pos), cm.cm_severity, cm.cm_depth);
+		ectx.gutter <- (IntMap.add cm.cm_depth gutter_len ectx.gutter);
+
+		(* Indent sub errors *)
+		let rec indent ?(acc=0) depth =
+			if depth = 0 then acc
+			else indent ~acc:(acc + try IntMap.find (depth-1) ectx.gutter with Not_found -> 3) (depth-1)
+		in
+
+		Some (
+			if cm.cm_depth > 0 then String.concat "\n" (List.map (fun str -> match str with
+				| "" -> ""
+				| _ -> (String.make (indent cm.cm_depth) ' ') ^ str
+			) (ExtString.String.nsplit !out "\n"))
+			else !out
+		)
+	end
+
+let compiler_message_string ectx cm =
+	let str = match cm.cm_severity with
+		| MessageSeverity.Warning -> "Warning : " ^ cm.cm_message
+		| Information | Error | Hint -> cm.cm_message
+	in
+
+	if cm.cm_pos = null_pos then
+		Some str
+	else begin
+		let epos =
+			if ectx.absolute_positions then TPrinting.Printer.s_pos cm.cm_pos
+			else Lexer.get_error_pos error_printer cm.cm_pos
+		in
+		let str =
+			let lines =
+				match (ExtString.String.nsplit str "\n") with
+				| first :: rest -> first :: List.map Error.compl_msg rest
+				| l -> l
+			in
+			String.concat ("\n" ^ epos ^ " : ") lines
+		in
+		Some (Printf.sprintf "%s : %s" epos str)
+	end
+
+let compiler_indented_message_string ectx cm =
+	match cm.cm_message with
+	(* Filter some messages that don't add much when using this message renderer *)
+	| "End of overload failure reasons" -> None
+	| _ ->
+		let str = match cm.cm_severity with
+			| MessageSeverity.Warning -> "Warning : " ^ cm.cm_message
+			| Information -> "Info : " ^ cm.cm_message
+			| Error | Hint -> cm.cm_message
+		in
+
+		if cm.cm_pos = null_pos then
+			Some str
+		else begin
+			let epos =
+				if ectx.absolute_positions then TPrinting.Printer.s_pos cm.cm_pos
+				else Lexer.get_error_pos error_printer cm.cm_pos
+			in
+			let lines =
+				match (ExtString.String.nsplit str "\n") with
+				| first :: rest -> (cm.cm_depth, first) :: List.map (fun msg -> (cm.cm_depth+1, msg)) rest
+				| l -> [(cm.cm_depth, List.hd l)]
+			in
+			let rm_prefix str = if (ExtString.String.starts_with str "... ") then String.sub str 4 ((String.length str) - 4) else str in
+			Some (String.concat "\n" (List.map (fun (depth, msg) -> (String.make (depth*2) ' ') ^ epos ^ " : " ^ (rm_prefix msg)) lines))
+		end
+
+let get_max_line max_lines messages =
+	List.fold_left (fun max_lines cm ->
+		let _,_,l2,_ = Lexer.get_pos_coords cm.cm_pos in
+		let old = try IntMap.find cm.cm_depth max_lines with Not_found -> 0 in
+
+		if l2 > old then IntMap.add cm.cm_depth l2 max_lines
+		else max_lines
+	) max_lines messages
+
+exception ConfigError of string
+
+let get_formatter com def default =
+	let format_mode = Define.defined_value_safe ~default com.defines def in
+	match format_mode with
+		| "pretty" -> compiler_pretty_message_string com
+		| "indent" -> compiler_indented_message_string
+		| "classic" -> compiler_message_string
+		| m -> begin
+			let def = Define.get_define_key def in
+			raise (ConfigError (Printf.sprintf "Invalid message reporting mode: \"%s\", expected classic | pretty | indent (for -D %s)." m def))
+		end
+
+let print_error (err : Error.error) =
+	let ret = ref "" in
+	Error.recurse_error (fun depth err ->
+		ret := !ret ^ (Lexer.get_error_pos (Printf.sprintf "%s:%d: ") err.err_pos) ^ (Error.error_msg err.err_message) ^ "\n"
+	) err;
+	!ret
+
+let format_messages com messages =
+	let absolute_positions = Define.defined com.defines Define.MessageAbsolutePositions in
+	let ectx = create_error_context absolute_positions in
+	ectx.max_lines <- get_max_line ectx.max_lines messages;
+	let message_formatter = get_formatter com Define.MessageReporting "classic" in
+	let lines = List.rev (
+		List.fold_left (fun lines cm -> match (message_formatter ectx cm) with
+			| None -> lines
+			| Some str -> str :: lines
+		) [] messages
+	) in
+	ExtLib.String.join "\n" lines
+
+let display_messages ctx on_message = begin
+	let absolute_positions = Define.defined ctx.com.defines Define.MessageAbsolutePositions in
+	let ectx = create_error_context absolute_positions in
+	ectx.max_lines <- get_max_line ectx.max_lines ctx.messages;
+
+	let get_formatter _ def default =
+		try get_formatter ctx.com def default
+		with | ConfigError s ->
+			error ctx s null_pos;
+			compiler_message_string
+	in
+
+	let message_formatter = get_formatter ctx.com Define.MessageReporting "classic" in
+	let log_formatter = get_formatter ctx.com Define.MessageLogFormat "indent" in
+
+	let log_messages = ref (Define.defined ctx.com.defines Define.MessageLogFile) in
+	let log_message = ref None in
+	let close_logs = ref None in
+
+	if !log_messages then begin
+		try begin
+			let buf = Rbuffer.create 16000 in
+
+			let file = Define.defined_value ctx.com.defines Define.MessageLogFile in
+			let chan =
+				Path.mkdir_from_path file;
+				open_out_bin file
+			in
+
+			log_message := (Some (fun msg ->
+				match (log_formatter ectx msg) with
+					| None -> ()
+					| Some str -> Rbuffer.add_string buf (str ^ "\n")));
+
+			close_logs := (Some (fun () ->
+				Rbuffer.output_buffer chan buf;
+				Rbuffer.clear buf;
+				close_out chan
+			));
+		end with
+			| Failure e | Sys_error e -> begin
+				let def = Define.get_define_key Define.MessageLogFile in
+				error ctx (Printf.sprintf "Error opening log file: %s. Logging to file disabled (-D %s)" e def) null_pos;
+				log_messages := false;
+			end
+	end;
+
+	List.iter (fun cm ->
+		if !log_messages then (Option.get !log_message) cm;
+
+		match (message_formatter ectx cm) with
+			| None -> ()
+			| Some str -> on_message cm.cm_severity str
+	) (List.rev ctx.messages);
+
+	if !log_messages then (Option.get !close_logs) ();
+end
+

+ 18 - 20
src/compiler/retyper.ml

@@ -21,7 +21,7 @@ let disable_typeloading rctx ctx f =
 	ctx.g.load_only_cached_modules <- true;
 	ctx.g.load_only_cached_modules <- true;
 	try
 	try
 		Std.finally (fun () -> ctx.g.load_only_cached_modules <- old) f ()
 		Std.finally (fun () -> ctx.g.load_only_cached_modules <- old) f ()
-	with (Error.Error (Module_not_found path,_,_)) ->
+	with (Error.Error { err_message = Module_not_found path }) ->
 		fail rctx (Printf.sprintf "Could not load [Module %s]" (s_type_path path))
 		fail rctx (Printf.sprintf "Could not load [Module %s]" (s_type_path path))
 
 
 let pair_type th t = match th with
 let pair_type th t = match th with
@@ -74,13 +74,13 @@ let pair_class_field rctx ctx cctx fctx cf cff p =
 				remove_class_field_flag cf CfPostProcessed;
 				remove_class_field_flag cf CfPostProcessed;
 		)
 		)
 
 
-let pair_classes rctx context_init c d p =
+let pair_classes rctx c d p =
 	let rctx = {rctx with
 	let rctx = {rctx with
 		print_stack = (Printf.sprintf "[Class %s]" (s_type_path c.cl_path)) :: rctx.print_stack
 		print_stack = (Printf.sprintf "[Class %s]" (s_type_path c.cl_path)) :: rctx.print_stack
 	} in
 	} in
 	c.cl_restore();
 	c.cl_restore();
 	(* TODO: What do we do with build macros? *)
 	(* TODO: What do we do with build macros? *)
-	let cctx = create_class_context c context_init p in
+	let cctx = create_class_context c p in
 	let ctx = create_typer_context_for_class rctx.typer cctx p in
 	let ctx = create_typer_context_for_class rctx.typer cctx p in
 	let _ =
 	let _ =
 		let rctx = {rctx with
 		let rctx = {rctx with
@@ -89,16 +89,16 @@ let pair_classes rctx context_init c d p =
 		let has_extends = ref false in
 		let has_extends = ref false in
 		let implements = ref c.cl_implements in
 		let implements = ref c.cl_implements in
 		List.iter (function
 		List.iter (function
-			| HExtends(path,p) ->
+			| HExtends ptp ->
 				has_extends := true;
 				has_extends := true;
 				begin match c.cl_super with
 				begin match c.cl_super with
 				| None ->
 				| None ->
-					fail rctx (Printf.sprintf "parent %s appeared" (Ast.Printer.s_complex_type_path "" (path,p)))
+					fail rctx (Printf.sprintf "parent %s appeared" (Ast.Printer.s_complex_type_path "" ptp))
 				| Some(c,tl) ->
 				| Some(c,tl) ->
-					let th = pair_type (Some(CTPath path,p)) (TInst(c,tl)) in
+					let th = pair_type (Some(CTPath ptp,ptp.pos_full)) (TInst(c,tl)) in
 					ignore (disable_typeloading rctx ctx (fun () -> Typeload.load_complex_type ctx false th))
 					ignore (disable_typeloading rctx ctx (fun () -> Typeload.load_complex_type ctx false th))
 				end
 				end
-			| HImplements(path,p) ->
+			| HImplements ptp ->
 				begin match !implements with
 				begin match !implements with
 					| (c,tl) :: rest ->
 					| (c,tl) :: rest ->
 						(* TODO: I think this should somehow check if it's actually the same interface. There could be cases
 						(* TODO: I think this should somehow check if it's actually the same interface. There could be cases
@@ -106,10 +106,10 @@ let pair_classes rctx context_init c d p =
 						   However, this doesn't matter until we start retyping invalidated modules.
 						   However, this doesn't matter until we start retyping invalidated modules.
 						*)
 						*)
 						implements := rest;
 						implements := rest;
-						let th = pair_type (Some(CTPath path,p)) (TInst(c,tl)) in
+						let th = pair_type (Some(CTPath ptp,ptp.pos_full)) (TInst(c,tl)) in
 						ignore (disable_typeloading rctx ctx (fun () -> Typeload.load_complex_type ctx false th));
 						ignore (disable_typeloading rctx ctx (fun () -> Typeload.load_complex_type ctx false th));
 					| [] ->
 					| [] ->
-						fail rctx (Printf.sprintf "interface %s appeared" (Ast.Printer.s_complex_type_path "" (path,p)))
+						fail rctx (Printf.sprintf "interface %s appeared" (Ast.Printer.s_complex_type_path "" ptp))
 				end
 				end
 			| _ ->
 			| _ ->
 				()
 				()
@@ -130,7 +130,7 @@ let pair_classes rctx context_init c d p =
 			print_stack = (Printf.sprintf "[Field %s]" name) :: rctx.print_stack
 			print_stack = (Printf.sprintf "[Field %s]" name) :: rctx.print_stack
 		} in
 		} in
 		let display_modifier = Typeload.check_field_access ctx cff in
 		let display_modifier = Typeload.check_field_access ctx cff in
-		let fctx = create_field_context cctx cff ctx.is_display_file display_modifier in
+		let fctx = create_field_context ctx cctx cff ctx.is_display_file display_modifier in
 		let cf = match fctx.field_kind with
 		let cf = match fctx.field_kind with
 			| FKConstructor ->
 			| FKConstructor ->
 				begin match c.cl_constructor with
 				begin match c.cl_constructor with
@@ -180,14 +180,14 @@ let pair_typedefs ctx rctx td d =
 	ignore (disable_typeloading rctx ctx (fun () -> Typeload.load_complex_type ctx false d.d_data));
 	ignore (disable_typeloading rctx ctx (fun () -> Typeload.load_complex_type ctx false d.d_data));
 	[]
 	[]
 
 
-let pair_abstracts ctx rctx context_init a d p =
+let pair_abstracts ctx rctx a d p =
 	let rctx = {rctx with
 	let rctx = {rctx with
 		print_stack = (Printf.sprintf "[Abstract %s]" (s_type_path a.a_path)) :: rctx.print_stack
 		print_stack = (Printf.sprintf "[Abstract %s]" (s_type_path a.a_path)) :: rctx.print_stack
 	} in
 	} in
 	match a.a_impl with
 	match a.a_impl with
 	| Some c ->
 	| Some c ->
 		c.cl_restore();
 		c.cl_restore();
-		let cctx = create_class_context c context_init p in
+		let cctx = create_class_context c p in
 		let ctx = create_typer_context_for_class rctx.typer cctx p in
 		let ctx = create_typer_context_for_class rctx.typer cctx p in
 		let fl = List.map (fun cff ->
 		let fl = List.map (fun cff ->
 			let cff = TypeloadFields.transform_abstract_field2 ctx a cff in
 			let cff = TypeloadFields.transform_abstract_field2 ctx a cff in
@@ -196,7 +196,7 @@ let pair_abstracts ctx rctx context_init a d p =
 				print_stack = (Printf.sprintf "[Field %s]" name) :: rctx.print_stack
 				print_stack = (Printf.sprintf "[Field %s]" name) :: rctx.print_stack
 			} in
 			} in
 			let display_modifier = Typeload.check_field_access ctx cff in
 			let display_modifier = Typeload.check_field_access ctx cff in
-			let fctx = create_field_context cctx cff ctx.is_display_file display_modifier in
+			let fctx = create_field_context ctx cctx cff ctx.is_display_file display_modifier in
 			let cf = try
 			let cf = try
 				PMap.find name c.cl_statics
 				PMap.find name c.cl_statics
 			with Not_found ->
 			with Not_found ->
@@ -218,7 +218,6 @@ let attempt_retyping ctx m p =
 		print_stack = [Printf.sprintf "[Module %s]" (s_type_path m.m_path)];
 		print_stack = [Printf.sprintf "[Module %s]" (s_type_path m.m_path)];
 	} in
 	} in
 	(* log rctx 0 (Printf.sprintf "Retyping module %s" (s_type_path m.m_path)); *)
 	(* log rctx 0 (Printf.sprintf "Retyping module %s" (s_type_path m.m_path)); *)
-	let context_init = new TypeloadFields.context_init in
 	let find_type name = try
 	let find_type name = try
 		List.find (fun t -> snd (t_infos t).mt_path = name) ctx.m.curmod.m_types
 		List.find (fun t -> snd (t_infos t).mt_path = name) ctx.m.curmod.m_types
 	with Not_found ->
 	with Not_found ->
@@ -230,11 +229,11 @@ let attempt_retyping ctx m p =
 		| (d,p) :: decls ->
 		| (d,p) :: decls ->
 			begin match d with
 			begin match d with
 			| EImport (path,mode) ->
 			| EImport (path,mode) ->
-				ImportHandling.init_import ctx context_init path mode p;
+				ImportHandling.init_import ctx path mode p;
 				ImportHandling.commit_import ctx path mode p;
 				ImportHandling.commit_import ctx path mode p;
 				loop acc decls
 				loop acc decls
 			| EUsing path ->
 			| EUsing path ->
-				ImportHandling.init_using ctx context_init path p;
+				ImportHandling.init_using ctx path p;
 				loop acc decls
 				loop acc decls
 			| EClass c ->
 			| EClass c ->
 				let mt = find_type (fst c.d_name) in
 				let mt = find_type (fst c.d_name) in
@@ -257,18 +256,17 @@ let attempt_retyping ctx m p =
 		let pairs = loop [] decls in
 		let pairs = loop [] decls in
 		let fl = List.map (fun (d,mt) -> match d,mt with
 		let fl = List.map (fun (d,mt) -> match d,mt with
 			| EClass d,TClassDecl c ->
 			| EClass d,TClassDecl c ->
-				pair_classes rctx context_init c d p
+				pair_classes rctx c d p
 			| EEnum d,TEnumDecl en ->
 			| EEnum d,TEnumDecl en ->
 				pair_enums ctx rctx en d
 				pair_enums ctx rctx en d
 			| ETypedef d,TTypeDecl td ->
 			| ETypedef d,TTypeDecl td ->
 				pair_typedefs ctx rctx td d
 				pair_typedefs ctx rctx td d
 			| EAbstract d,TAbstractDecl a ->
 			| EAbstract d,TAbstractDecl a ->
-				pair_abstracts ctx rctx context_init a d p
+				pair_abstracts ctx rctx a d p
 			| _ ->
 			| _ ->
 				fail rctx "?"
 				fail rctx "?"
 		) pairs in
 		) pairs in
 		(* If we get here we know that the everything is ok. *)
 		(* If we get here we know that the everything is ok. *)
-		delay ctx PConnectField (fun () -> context_init#run);
 		List.iter (fun fl ->
 		List.iter (fun fl ->
 			List.iter (fun f -> f()) fl
 			List.iter (fun f -> f()) fl
 		) fl;
 		) fl;
@@ -276,4 +274,4 @@ let attempt_retyping ctx m p =
 		m.m_extra.m_time <- Common.file_time file;
 		m.m_extra.m_time <- Common.file_time file;
 		None
 		None
 	with Fail s ->
 	with Fail s ->
-		Some s
+		Some s

+ 91 - 413
src/compiler/server.ml

@@ -1,15 +1,13 @@
-open Extlib_leftovers
-open Printf
 open Globals
 open Globals
-open Ast
 open Common
 open Common
 open CompilationCache
 open CompilationCache
 open Timer
 open Timer
 open Type
 open Type
 open DisplayProcessingGlobals
 open DisplayProcessingGlobals
+open Ipaddr
 open Json
 open Json
-open Compiler
 open CompilationContext
 open CompilationContext
+open MessageReporting
 
 
 exception Dirty of module_skip_reason
 exception Dirty of module_skip_reason
 exception ServerError of string
 exception ServerError of string
@@ -18,15 +16,7 @@ let has_error ctx =
 	ctx.has_error || ctx.com.Common.has_error
 	ctx.has_error || ctx.com.Common.has_error
 
 
 let check_display_flush ctx f_otherwise = match ctx.com.json_out with
 let check_display_flush ctx f_otherwise = match ctx.com.json_out with
-	| None ->
-		if is_diagnostics ctx.com then begin
-			List.iter (fun cm ->
-				add_diagnostics_message ctx.com (located cm.cm_message cm.cm_pos) cm.cm_kind cm.cm_severity
-			) (List.rev ctx.messages);
-			raise (Completion (Diagnostics.print ctx.com))
-		end else
-			f_otherwise ()
-	| Some api ->
+	| Some api when not (is_diagnostics ctx.com) ->
 		if has_error ctx then begin
 		if has_error ctx then begin
 			let errors = List.map (fun cm ->
 			let errors = List.map (fun cm ->
 				JObject [
 				JObject [
@@ -37,6 +27,17 @@ let check_display_flush ctx f_otherwise = match ctx.com.json_out with
 			) (List.rev ctx.messages) in
 			) (List.rev ctx.messages) in
 			api.send_error errors
 			api.send_error errors
 		end
 		end
+	| _ ->
+		if is_diagnostics ctx.com then begin
+			List.iter (fun cm ->
+				add_diagnostics_message ~depth:cm.cm_depth ctx.com cm.cm_message cm.cm_pos cm.cm_kind cm.cm_severity
+			) (List.rev ctx.messages);
+			(match ctx.com.report_mode with
+			| RMDiagnostics _ -> ()
+			| RMLegacyDiagnostics _ -> raise (Completion (Diagnostics.print ctx.com))
+			| _ -> die "" __LOC__)
+		end else
+			f_otherwise ()
 
 
 let current_stdin = ref None
 let current_stdin = ref None
 
 
@@ -46,7 +47,7 @@ let parse_file cs com file p =
 	and fkey = com.file_keys#get file in
 	and fkey = com.file_keys#get file in
 	let is_display_file = DisplayPosition.display_position#is_in_file (com.file_keys#get ffile) in
 	let is_display_file = DisplayPosition.display_position#is_in_file (com.file_keys#get ffile) in
 	match is_display_file, !current_stdin with
 	match is_display_file, !current_stdin with
-	| true, Some stdin when Common.defined com Define.DisplayStdin ->
+	| true, Some stdin when (com.file_contents <> [] || Common.defined com Define.DisplayStdin) ->
 		TypeloadParse.parse_file_from_string com file p stdin
 		TypeloadParse.parse_file_from_string com file p stdin
 	| _ ->
 	| _ ->
 		let ftime = file_time ffile in
 		let ftime = file_time ffile in
@@ -87,365 +88,6 @@ let parse_file cs com file p =
 open ServerCompilationContext
 open ServerCompilationContext
 
 
 module Communication = struct
 module Communication = struct
-	type error_context = {
-		mutable last_positions : pos IntMap.t;
-		mutable max_lines : int IntMap.t;
-		mutable gutter : int IntMap.t;
-		mutable previous : (pos * MessageSeverity.t * int) option;
-	}
-
-	let create_error_context () = {
-		last_positions = IntMap.empty;
-		max_lines = IntMap.empty;
-		gutter = IntMap.empty;
-		previous = None;
-	}
-
-	let error_printer file line = Printf.sprintf "%s:%d:" file line
-
-	let resolve_source file l1 p1 l2 p2 =
-		let ch = open_in_bin file in
-		let curline = ref 1 in
-		let lines = ref [] in
-		let rec loop p line =
-			let inc i line =
-				if (!curline >= l1) && (!curline <= l2) then lines := (!curline, line) :: !lines;
-				curline := !curline + 1;
-				(i, "")
-			in
-
-			let input_char_or_done ch line =
-				try input_char ch with End_of_file -> begin
-					ignore(inc 0 line);
-					raise End_of_file
-				end
-			in
-
-			try
-				let read_char line = match input_char_or_done ch line with
-					| '\n' -> inc 1 line
-					| '\r' ->
-						ignore(input_char_or_done ch line);
-						inc 2 line
-					| c -> begin
-						let line = ref (line ^ (String.make 1 c)) in
-						let rec skip n =
-							if n > 0 then begin
-								let c = input_char_or_done ch !line in
-								line := !line ^ (String.make 1 c);
-								skip (n - 1)
-							end
-						in
-
-						let code = int_of_char c in
-						if code < 0xC0 then ()
-						else if code < 0xE0 then skip 1
-						else if code < 0xF0 then skip 2
-						else skip 3;
-
-						(1, !line)
-					end
-				in
-
-				let (delta, line) = read_char line in
-				loop (p + delta) line
-			with End_of_file ->
-				close_in ch;
-		in
-
-		loop 0 "";
-		List.rev !lines
-
-	let resolve_file ctx f =
-			let ext = Common.extension f in
-			let second_ext = Common.extension (Common.remove_extension f) in
-			let platform_ext = "." ^ (platform_name_macro ctx) in
-			if platform_ext = second_ext then
-				(Common.remove_extension (Common.remove_extension f)) ^ ext
-			else
-				f
-
-	let compiler_pretty_message_string ctx ectx cm =
-		match cm.cm_message with
-		(* Filter some messages that don't add much when using this message renderer *)
-		| "End of overload failure reasons" -> None
-		| _ -> begin
-			ectx.last_positions <- (IntMap.add cm.cm_depth cm.cm_pos ectx.last_positions);
-			let is_null_pos = cm.cm_pos = null_pos || cm.cm_pos.pmin = -1 in
-			let is_unknown_file f = f = "" || f = "?" in
-
-			(* Extract informations from position *)
-			let l1, p1, l2, p2, epos, lines =
-				if is_null_pos then begin
-					let epos = if is_unknown_file cm.cm_pos.pfile then "(unknown position)" else cm.cm_pos.pfile in
-					(-1, -1, -1, -1, epos, [])
-				end else begin
-					let f = resolve_file ctx.com cm.cm_pos.pfile in
-					let f =
-						try Common.find_file ctx.com f
-						with Not_found -> failwith ("File not found '" ^ cm.cm_pos.pfile ^ "'")
-						in
-
-					let l1, p1, l2, p2 = Lexer.get_pos_coords cm.cm_pos in
-					let lines = resolve_source f l1 p1 l2 p2 in
-					let epos = Lexer.get_error_pos error_printer cm.cm_pos in
-					(l1, p1, l2, p2, epos, lines)
-				end in
-
-			(* If 4 lines or less, display all; if more, crop the middle *)
-			let lines = match lines with
-				| _ :: (_ :: (_ :: (_ :: []))) -> lines
-				| hd :: (_ :: (_ :: (_ :: l))) ->
-					let _,line = hd in
-					let indent = ref 0 in
-					let found = ref false in
-
-					while (not !found) && (!indent < (String.length line - 1)) do
-						found := not (Lexer.is_whitespace (String.unsafe_get line !indent));
-						indent := !indent + 1
-					done;
-
-					[hd; (0, (String.make (!indent+1) ' ') ^ "[...]"); List.hd (List.rev l)]
-				| _ -> lines
-			in
-
-			let parent_pos =
-				if cm.cm_depth = 0 then null_pos
-				else (try IntMap.find (cm.cm_depth-1) ectx.last_positions with Not_found -> null_pos)
-			in
-
-			let prev_pos,prev_sev,prev_nl = match ectx.previous with
-				| None -> (None, None, 0)
-				| Some (p, sev, depth) -> (Some p, Some sev, depth)
-			in
-
-			let sev_changed = prev_sev = None || Some cm.cm_severity <> prev_sev in
-			let pos_changed = (prev_pos = None || cm.cm_pos <> Option.get prev_pos || (cm.cm_depth <> prev_nl && cm.cm_depth <> prev_nl + 1)) && (parent_pos = null_pos || cm.cm_pos <> parent_pos) in
-			let file_changed = prev_pos = None || (pos_changed && match (cm.cm_pos.pfile, (Option.get prev_pos).pfile) with
-				| (f1, f2) when (is_unknown_file f1) && (is_unknown_file f2) -> false
-				| (f1, f2) -> f1 <> f2
-			) in
-
-			let display_heading = cm.cm_depth = 0 || sev_changed || file_changed in
-			let display_source = cm.cm_depth = 0 || sev_changed || pos_changed in
-			let display_pos_marker = (not is_null_pos) && (cm.cm_depth = 0 || sev_changed || pos_changed) in
-
-			let gutter_len = (try String.length (Printf.sprintf "%d" (IntMap.find cm.cm_depth ectx.max_lines)) with Not_found -> 0) + 2 in
-
-			let no_color = Define.defined ctx.com.defines Define.NoColor in
-			let c_reset = if no_color then "" else "\x1b[0m" in
-			let c_bold = if no_color then "" else "\x1b[1m" in
-			let c_dim = if no_color then "" else "\x1b[2m" in
-
-			let (c_sev, c_sev_bg) = if no_color then ("", "") else match cm.cm_severity with
-				| MessageSeverity.Warning -> ("\x1b[33m", "\x1b[30;43m")
-				| Information | Hint -> ("\x1b[34m", "\x1b[30;44m")
-				| Error -> ("\x1b[31m", "\x1b[30;41m")
-			in
-
-			let sev_label = if cm.cm_depth > 0 then " -> " else Printf.sprintf
-				(if no_color then "[%s]" else " %s ")
-				(match cm.cm_severity with
-					| MessageSeverity.Warning -> "WARNING"
-					| Information -> "INFO"
-					| Hint -> "HINT"
-					| Error -> "ERROR"
-				) in
-
-			let out = ref "" in
-
-			if display_heading then
-				out := Printf.sprintf "%s%s\n\n"
-					(* Severity heading *)
-					(c_sev_bg ^ sev_label ^ c_reset ^ " ")
-					(* File + line pointer *)
-					epos;
-
-			(* Error source *)
-			if display_source then out := List.fold_left (fun out (l, line) ->
-				let nb_len = String.length (string_of_int l) in
-
-				(* Replace tabs with 1 space to avoid column misalignments *)
-				let line = String.concat " " (ExtString.String.nsplit line "\t") in
-				let len = String.length line in
-
-				out ^ Printf.sprintf "%s%s | %s\n"
-					(* left-padded line number *)
-					(String.make (gutter_len-nb_len-1) ' ')
-					(if l = 0 then "-" else Printf.sprintf "%d" l)
-					(* Source code at that line *)
-					(
-						if l = 0 then
-							c_dim ^ line ^ c_reset
-						else if l1 = l2 then
-							(if p1 > 1 then c_dim ^ (String.sub line 0 (p1-1)) else "")
-							^ c_reset ^ c_bold ^ (String.sub line (p1-1) (p2-p1))
-							^ c_reset ^ c_dim ^ (String.sub line (p2-1) (len - p2 + 1))
-							^ c_reset
-						else begin
-							(if (l = l1) then
-								(if p1 > 1 then c_dim ^ (String.sub line 0 (p1-1)) else "")
-								^ c_reset ^ c_bold ^ (String.sub line (p1-1) (len-p1+1))
-								^ c_reset
-							else if (l = l2) then
-								(if p2 > 1 then c_bold ^ (String.sub line 0 (p2-1)) else "")
-								^ c_reset ^ c_dim ^ (String.sub line (p2-1) (len-p2+1))
-								^ c_reset
-							else c_bold ^ line ^ c_reset)
-						end
-					)
-			) !out lines;
-
-			(* Error position marker *)
-			if display_pos_marker then
-				out := Printf.sprintf "%s%s|%s\n"
-					!out
-					(String.make gutter_len ' ')
-					(if l1 = l2 then String.make p1 ' ' ^ c_sev ^ String.make (if p1 = p2 then 1 else p2-p1) '^' ^ c_reset else "");
-
-			(* Error message *)
-			out := List.fold_left (fun out str -> Printf.sprintf "%s%s| %s\n"
-				out
-				(String.make gutter_len ' ')
-				(* Remove "... " prefix *)
-				(if (ExtString.String.starts_with str "... ") then String.sub str 4 ((String.length str) - 4) else str)
-			) !out (ExtString.String.nsplit cm.cm_message "\n");
-
-			ectx.previous <- Some ((if is_null_pos then null_pos else cm.cm_pos), cm.cm_severity, cm.cm_depth);
-			ectx.gutter <- (IntMap.add cm.cm_depth gutter_len ectx.gutter);
-
-			(* Indent sub errors *)
-			let rec indent ?(acc=0) depth =
-				if depth = 0 then acc
-				else indent ~acc:(acc + try IntMap.find (depth-1) ectx.gutter with Not_found -> 3) (depth-1)
-			in
-
-			Some (
-				if cm.cm_depth > 0 then String.concat "\n" (List.map (fun str -> match str with
-					| "" -> ""
-					| _ -> (String.make (indent cm.cm_depth) ' ') ^ str
-				) (ExtString.String.nsplit !out "\n"))
-				else !out
-			)
-		end
-
-	let compiler_message_string ctx ectx cm =
-		let str = match cm.cm_severity with
-			| MessageSeverity.Warning -> "Warning : " ^ cm.cm_message
-			| Information | Error | Hint -> cm.cm_message
-		in
-
-		if cm.cm_pos = null_pos then
-			Some str
-		else begin
-			let epos = Lexer.get_error_pos error_printer cm.cm_pos in
-			let str =
-				let lines =
-					match (ExtString.String.nsplit str "\n") with
-					| first :: rest -> first :: List.map Error.compl_msg rest
-					| l -> l
-				in
-				String.concat ("\n" ^ epos ^ " : ") lines
-			in
-			Some (Printf.sprintf "%s : %s" epos str)
-		end
-
-	let compiler_indented_message_string ctx ectx cm =
-		match cm.cm_message with
-		(* Filter some messages that don't add much when using this message renderer *)
-		| "End of overload failure reasons" -> None
-		| _ ->
-			let str = match cm.cm_severity with
-				| MessageSeverity.Warning -> "Warning : " ^ cm.cm_message
-				| Information -> "Info : " ^ cm.cm_message
-				| Error | Hint -> cm.cm_message
-			in
-
-			if cm.cm_pos = null_pos then
-				Some str
-			else begin
-				let epos = Lexer.get_error_pos error_printer cm.cm_pos in
-				let lines =
-					match (ExtString.String.nsplit str "\n") with
-					| first :: rest -> (cm.cm_depth, first) :: List.map (fun msg -> (cm.cm_depth+1, msg)) rest
-					| l -> [(cm.cm_depth, List.hd l)]
-				in
-				let rm_prefix str = if (ExtString.String.starts_with str "... ") then String.sub str 4 ((String.length str) - 4) else str in
-				Some (String.concat "\n" (List.map (fun (depth, msg) -> (String.make (depth*2) ' ') ^ epos ^ " : " ^ (rm_prefix msg)) lines))
-			end
-
-	let get_max_line max_lines messages =
-		List.fold_left (fun max_lines cm ->
-			let _,_,l2,_ = Lexer.get_pos_coords cm.cm_pos in
-			let old = try IntMap.find cm.cm_depth max_lines with Not_found -> 0 in
-
-			if l2 > old then IntMap.add cm.cm_depth l2 max_lines
-			else max_lines
-		) max_lines messages
-
-	let display_messages ctx on_message = begin
-		let ectx = create_error_context () in
-		ectx.max_lines <- get_max_line ectx.max_lines ctx.messages;
-
-		let get_formatter def default =
-			let format_mode = Define.defined_value_safe ~default ctx.com.defines def in
-			match format_mode with
-				| "pretty" -> compiler_pretty_message_string ctx ectx
-				| "indent" -> compiler_indented_message_string ctx ectx
-				| "classic" -> compiler_message_string ctx ectx
-				| m -> begin
-					let def = Define.get_define_key def in
-					error ctx (Printf.sprintf "Invalid message reporting mode: \"%s\", expected classic | pretty | indent (for -D %s)." m def) null_pos;
-					compiler_message_string ctx ectx
-				end
-			in
-
-		let message_formatter = get_formatter Define.MessageReporting "classic" in
-		let log_formatter = get_formatter Define.MessagesLogFormat "indent" in
-
-		let log_messages = ref (Define.defined ctx.com.defines Define.MessagesLogFile) in
-		let log_message = ref None in
-		let close_logs = ref None in
-
-		if !log_messages then begin
-			try begin
-				let buf = Rbuffer.create 16000 in
-
-				let file = Define.defined_value ctx.com.defines Define.MessagesLogFile in
-				let chan =
-					Path.mkdir_from_path file;
-					open_out_bin file
-				in
-
-				log_message := (Some (fun msg ->
-					match (log_formatter msg) with
-						| None -> ()
-						| Some str -> Rbuffer.add_string buf (str ^ "\n")));
-
-				close_logs := (Some (fun () ->
-					Rbuffer.output_buffer chan buf;
-					Rbuffer.clear buf;
-					close_out chan
-				));
-			end with
-				| Failure e | Sys_error e -> begin
-					let def = Define.get_define_key Define.MessagesLogFile in
-					error ctx (Printf.sprintf "Error opening log file: %s. Logging to file disabled (-D %s)" e def) null_pos;
-					log_messages := false;
-				end
-		end;
-
-		List.iter (fun cm ->
-			if !log_messages then (Option.get !log_message) cm;
-
-			match (message_formatter cm) with
-				| None -> ()
-				| Some str -> on_message cm.cm_severity str
-		) (List.rev ctx.messages);
-
-		if !log_messages then (Option.get !close_logs) ();
-	end
-
 	let create_stdio () =
 	let create_stdio () =
 		let rec self = {
 		let rec self = {
 			write_out = (fun s ->
 			write_out = (fun s ->
@@ -479,32 +121,38 @@ module Communication = struct
 		} in
 		} in
 		self
 		self
 
 
-	let create_pipe sctx write = {
-		write_out = (fun s ->
-			write ("\x01" ^ String.concat "\x01" (ExtString.String.nsplit s "\n") ^ "\n")
-		);
-		write_err = (fun s ->
-			write s
-		);
-		flush = (fun ctx ->
-			check_display_flush ctx (fun () ->
-				display_messages ctx (fun _ output ->
-					write (output ^ "\n");
-					ServerMessage.message output;
-				);
-
-				sctx.was_compilation <- ctx.com.display.dms_full_typing;
-				if has_error ctx then begin
-					measure_times := false;
-					write "\x02\n"
-				end
-			)
-		);
-		exit = (fun i ->
-			()
-		);
-		is_server = true;
-	}
+	let create_pipe sctx write =
+		let rec self = {
+			write_out = (fun s ->
+				write ("\x01" ^ String.concat "\n\x01" (ExtString.String.nsplit s "\n") ^ "\n")
+			);
+			write_err = (fun s ->
+				write s
+			);
+			flush = (fun ctx ->
+				check_display_flush ctx (fun () ->
+					display_messages ctx (fun _ output ->
+						write (output ^ "\n");
+						ServerMessage.message output;
+					);
+
+					sctx.was_compilation <- ctx.com.display.dms_full_typing;
+					if has_error ctx then begin
+						measure_times := false;
+						write "\x02\n"
+					end else begin
+						Timer.close_times();
+						if !Timer.measure_times then Timer.report_times (fun s -> self.write_err (s ^ "\n"));
+					end
+				)
+			);
+			exit = (fun i ->
+				()
+			);
+			is_server = true;
+		}
+		in
+		self
 end
 end
 
 
 let stat dir =
 let stat dir =
@@ -643,7 +291,7 @@ let check_module sctx ctx m p =
 					raise (ServerError ("Infinite loop in Haxe server detected. "
 					raise (ServerError ("Infinite loop in Haxe server detected. "
 						^ "Probably caused by shadowing a module of the standard library. "
 						^ "Probably caused by shadowing a module of the standard library. "
 						^ "Make sure shadowed module does not pull macro context."));
 						^ "Make sure shadowed module does not pull macro context."));
-				let _, mctx = MacroContext.get_macro_context ctx p in
+				let mctx = MacroContext.get_macro_context ctx in
 				check_module_shadowing (get_changed_directories sctx mctx) m
 				check_module_shadowing (get_changed_directories sctx mctx) m
 		in
 		in
 		let has_policy policy = List.mem policy m.m_extra.m_check_policy || match policy with
 		let has_policy policy = List.mem policy m.m_extra.m_check_policy || match policy with
@@ -663,7 +311,9 @@ let check_module sctx ctx m p =
 			end
 			end
 		in
 		in
 		let check_dependencies () =
 		let check_dependencies () =
-			PMap.iter (fun _ m2 -> match check m2 with
+			PMap.iter (fun _ (sign,mpath) ->
+				let m2 = (com.cs#get_context sign)#find_module mpath in
+				match check m2 with
 				| None -> ()
 				| None -> ()
 				| Some reason -> raise (Dirty (DependencyDirty(m2.m_path,reason)))
 				| Some reason -> raise (Dirty (DependencyDirty(m2.m_path,reason)))
 			) m.m_extra.m_deps;
 			) m.m_extra.m_deps;
@@ -745,6 +395,16 @@ let check_module sctx ctx m p =
 	end;
 	end;
 	state
 	state
 
 
+let handle_cache_bound_objects com cbol =
+	DynArray.iter (function
+		| Resource(name,data) ->
+			Hashtbl.replace com.resources name data
+		| IncludeFile(file,position) ->
+			com.include_files <- (file,position) :: com.include_files
+		| Warning(w,msg,p) ->
+			com.warning w [] msg p
+	) cbol
+
 (* Adds module [m] and all its dependencies (recursively) from the cache to the current compilation
 (* Adds module [m] and all its dependencies (recursively) from the cache to the current compilation
    context. *)
    context. *)
 let add_modules sctx ctx m p =
 let add_modules sctx ctx m p =
@@ -754,7 +414,7 @@ let add_modules sctx ctx m p =
 			(match m0.m_extra.m_kind, m.m_extra.m_kind with
 			(match m0.m_extra.m_kind, m.m_extra.m_kind with
 			| MCode, MMacro | MMacro, MCode ->
 			| MCode, MMacro | MMacro, MCode ->
 				(* this was just a dependency to check : do not add to the context *)
 				(* this was just a dependency to check : do not add to the context *)
-				PMap.iter (Hashtbl.replace com.resources) m.m_extra.m_binded_res;
+				handle_cache_bound_objects com m.m_extra.m_cache_bound_objects;
 			| _ ->
 			| _ ->
 				m.m_extra.m_added <- ctx.com.compilation_step;
 				m.m_extra.m_added <- ctx.com.compilation_step;
 				ServerMessage.reusing com tabs m;
 				ServerMessage.reusing com tabs m;
@@ -762,8 +422,11 @@ let add_modules sctx ctx m p =
 					(t_infos t).mt_restore()
 					(t_infos t).mt_restore()
 				) m.m_types;
 				) m.m_types;
 				TypeloadModule.ModuleLevel.add_module ctx m p;
 				TypeloadModule.ModuleLevel.add_module ctx m p;
-				PMap.iter (Hashtbl.replace com.resources) m.m_extra.m_binded_res;
-				PMap.iter (fun _ m2 -> add_modules (tabs ^ "  ") m0 m2) m.m_extra.m_deps
+				handle_cache_bound_objects com m.m_extra.m_cache_bound_objects;
+				PMap.iter (fun _ (sign,mpath) ->
+					let m2 = (com.cs#get_context sign)#find_module mpath in
+					add_modules (tabs ^ "  ") m0 m2
+				) m.m_extra.m_deps
 			)
 			)
 		end
 		end
 	in
 	in
@@ -798,7 +461,7 @@ let type_module sctx (ctx:Typecore.typer) mpath p =
 let before_anything sctx ctx =
 let before_anything sctx ctx =
 	ensure_macro_setup sctx
 	ensure_macro_setup sctx
 
 
-let after_arg_parsing sctx ctx =
+let after_target_init sctx ctx =
 	let com = ctx.com in
 	let com = ctx.com in
 	let cs = sctx.cs in
 	let cs = sctx.cs in
 	let sign = Define.get_signature com.defines in
 	let sign = Define.get_signature com.defines in
@@ -893,9 +556,16 @@ let init_wait_stdio() =
 	mk_length_prefixed_communication false stdin stderr
 	mk_length_prefixed_communication false stdin stderr
 
 
 (* The connect function to connect to [host] at [port] and send arguments [args]. *)
 (* The connect function to connect to [host] at [port] and send arguments [args]. *)
-let do_connect host port args =
-	let sock = Unix.socket Unix.PF_INET Unix.SOCK_STREAM 0 in
-	(try Unix.connect sock (Unix.ADDR_INET (Unix.inet_addr_of_string host,port)) with _ -> failwith ("Couldn't connect on " ^ host ^ ":" ^ string_of_int port));
+let do_connect ip port args =
+	let (domain, host) = match ip with
+		| V4 ip -> (Unix.PF_INET, V4.to_string ip)
+		| V6 ip -> (Unix.PF_INET6, V6.to_string ip)
+	in
+	let sock = Unix.socket domain Unix.SOCK_STREAM 0 in
+	(try Unix.connect sock (Unix.ADDR_INET (Unix.inet_addr_of_string host,port)) with
+		| Unix.Unix_error(code,_,_) -> failwith("Couldn't connect on " ^ host ^ ":" ^ string_of_int port ^ " (" ^ (Unix.error_message code) ^ ")");
+		| _ -> failwith ("Couldn't connect on " ^ host ^ ":" ^ string_of_int port)
+	);
 	let rec display_stdin args =
 	let rec display_stdin args =
 		match args with
 		match args with
 		| [] -> ""
 		| [] -> ""
@@ -910,7 +580,7 @@ let do_connect host port args =
 	let s = (String.concat "" (List.map (fun a -> a ^ "\n") args)) ^ (display_stdin args) in
 	let s = (String.concat "" (List.map (fun a -> a ^ "\n") args)) ^ (display_stdin args) in
 	ssend sock (Bytes.of_string (s ^ "\000"));
 	ssend sock (Bytes.of_string (s ^ "\000"));
 	let has_error = ref false in
 	let has_error = ref false in
-	let rec print line =
+	let print line =
 		match (if line = "" then '\x00' else line.[0]) with
 		match (if line = "" then '\x00' else line.[0]) with
 		| '\x01' ->
 		| '\x01' ->
 			print_string (String.concat "\n" (List.tl (ExtString.String.nsplit line "\x01")));
 			print_string (String.concat "\n" (List.tl (ExtString.String.nsplit line "\x01")));
@@ -961,7 +631,7 @@ let rec process sctx comm args =
 		cache = sctx.cs;
 		cache = sctx.cs;
 		callbacks = {
 		callbacks = {
 			before_anything = before_anything sctx;
 			before_anything = before_anything sctx;
-			after_arg_parsing = after_arg_parsing sctx;
+			after_target_init = after_target_init sctx;
 			after_compilation = after_compilation sctx;
 			after_compilation = after_compilation sctx;
 		};
 		};
 		init_wait_socket = init_wait_socket;
 		init_wait_socket = init_wait_socket;
@@ -1058,14 +728,22 @@ and wait_loop verbose accept =
 	0
 	0
 
 
 (* Connect to given host/port and return accept function for communication *)
 (* Connect to given host/port and return accept function for communication *)
-and init_wait_connect host port =
+and init_wait_connect ip port =
+	let host = match ip with
+		| V4 ip -> V4.to_string ip
+		| V6 ip -> V6.to_string ip
+	in
 	let host = Unix.inet_addr_of_string host in
 	let host = Unix.inet_addr_of_string host in
 	let chin, chout = Unix.open_connection (Unix.ADDR_INET (host,port)) in
 	let chin, chout = Unix.open_connection (Unix.ADDR_INET (host,port)) in
 	mk_length_prefixed_communication true chin chout
 	mk_length_prefixed_communication true chin chout
 
 
 (* The accept-function to wait for a socket connection. *)
 (* The accept-function to wait for a socket connection. *)
-and init_wait_socket host port =
-	let sock = Unix.socket Unix.PF_INET Unix.SOCK_STREAM 0 in
+and init_wait_socket ip port =
+	let (domain, host) = match ip with
+		| V4 ip -> (Unix.PF_INET, V4.to_string ip)
+		| V6 ip -> (Unix.PF_INET6, V6.to_string ip)
+	in
+	let sock = Unix.socket domain Unix.SOCK_STREAM 0 in
 	(try Unix.setsockopt sock Unix.SO_REUSEADDR true with _ -> ());
 	(try Unix.setsockopt sock Unix.SO_REUSEADDR true with _ -> ());
 	(try Unix.bind sock (Unix.ADDR_INET (Unix.inet_addr_of_string host,port)) with _ -> failwith ("Couldn't wait on " ^ host ^ ":" ^ string_of_int port));
 	(try Unix.bind sock (Unix.ADDR_INET (Unix.inet_addr_of_string host,port)) with _ -> failwith ("Couldn't wait on " ^ host ^ ":" ^ string_of_int port));
 	ServerMessage.socket_message ("Waiting on " ^ host ^ ":" ^ string_of_int port);
 	ServerMessage.socket_message ("Waiting on " ^ host ^ ":" ^ string_of_int port);

+ 7 - 3
src/compiler/serverCompilationContext.ml

@@ -58,7 +58,7 @@ let reset sctx =
 	Helper.start_time := get_time()
 	Helper.start_time := get_time()
 
 
 let maybe_cache_context sctx com =
 let maybe_cache_context sctx com =
-	if com.display.dms_full_typing then begin
+	if com.display.dms_full_typing && com.display.dms_populate_cache then begin
 		CommonCache.cache_context sctx.cs com;
 		CommonCache.cache_context sctx.cs com;
 		ServerMessage.cached_modules com "" (List.length com.modules);
 		ServerMessage.cached_modules com "" (List.length com.modules);
 	end
 	end
@@ -70,5 +70,9 @@ let ensure_macro_setup sctx =
 	end
 	end
 
 
 let cleanup () = match !MacroContext.macro_interp_cache with
 let cleanup () = match !MacroContext.macro_interp_cache with
-	| Some interp -> EvalContext.GlobalState.cleanup interp
-	| None -> ()
+	| Some interp ->
+		(* curapi holds a reference to the typing context which we don't want to persist. Let's unset it so the
+		   context can be collected. *)
+		interp.curapi <- Obj.magic ""
+	| None ->
+		()

+ 2 - 1
src/compiler/serverConfig.ml

@@ -1,2 +1,3 @@
 let do_not_check_modules = ref false
 let do_not_check_modules = ref false
-let legacy_completion = ref false
+let populate_cache_from_display = ref true
+let legacy_completion = ref false

+ 7 - 1
src/compiler/serverMessage.ml

@@ -2,9 +2,9 @@ open Globals
 open Common
 open Common
 open CompilationCache
 open CompilationCache
 open Type
 open Type
-open Json
 
 
 type server_message_options = {
 type server_message_options = {
+	mutable print_compiler_stage : bool;
 	mutable print_added_directory : bool;
 	mutable print_added_directory : bool;
 	mutable print_found_directories : bool;
 	mutable print_found_directories : bool;
 	mutable print_changed_directories : bool;
 	mutable print_changed_directories : bool;
@@ -31,6 +31,7 @@ type server_message_options = {
 }
 }
 
 
 let config = {
 let config = {
+	print_compiler_stage = false;
 	print_added_directory = false;
 	print_added_directory = false;
 	print_found_directories = false;
 	print_found_directories = false;
 	print_changed_directories = false;
 	print_changed_directories = false;
@@ -62,6 +63,9 @@ let sign_string com =
 	let	sign_id = (cs#get_context sign)#get_index in
 	let	sign_id = (cs#get_context sign)#get_index in
 	Printf.sprintf "%2i,%3s: " sign_id (short_platform_name com.platform)
 	Printf.sprintf "%2i,%3s: " sign_id (short_platform_name com.platform)
 
 
+let compiler_stage com =
+	if config.print_compiler_stage then print_endline (Printf.sprintf "compiler stage: %s" (s_compiler_stage com.stage))
+
 let added_directory com tabs dir =
 let added_directory com tabs dir =
 	if config.print_added_directory then print_endline (Printf.sprintf "%sadded directory %s" (sign_string com) dir)
 	if config.print_added_directory then print_endline (Printf.sprintf "%sadded directory %s" (sign_string com) dir)
 
 
@@ -157,6 +161,7 @@ let uncaught_error s =
 	if config.print_uncaught_error then print_endline ("Uncaught Error : " ^ s)
 	if config.print_uncaught_error then print_endline ("Uncaught Error : " ^ s)
 
 
 let enable_all () =
 let enable_all () =
+	config.print_compiler_stage <- true;
 	config.print_added_directory <- true;
 	config.print_added_directory <- true;
 	config.print_found_directories <- true;
 	config.print_found_directories <- true;
 	config.print_changed_directories <- true;
 	config.print_changed_directories <- true;
@@ -181,6 +186,7 @@ let enable_all () =
 	config.print_new_context <- true
 	config.print_new_context <- true
 
 
 let set_by_name name value = match name with
 let set_by_name name value = match name with
+	| "compilerStage" -> config.print_compiler_stage <- value
 	| "addedDirectory" -> config.print_added_directory <- value
 	| "addedDirectory" -> config.print_added_directory <- value
 	| "foundDirectories" -> config.print_found_directories <- value;
 	| "foundDirectories" -> config.print_found_directories <- value;
 	| "changedDirectories" -> config.print_changed_directories <- value;
 	| "changedDirectories" -> config.print_changed_directories <- value;

+ 23 - 21
src/context/abstractCast.ml

@@ -4,7 +4,6 @@ open Ast
 open Type
 open Type
 open Typecore
 open Typecore
 open Error
 open Error
-open CallUnification
 
 
 let cast_stack = new_rec_stack()
 let cast_stack = new_rec_stack()
 
 
@@ -15,11 +14,11 @@ let rec make_static_call ctx c cf a pl args t p =
 				let e,f = push_this ctx e in
 				let e,f = push_this ctx e in
 				ctx.with_type_stack <- (WithType.with_type t) :: ctx.with_type_stack;
 				ctx.with_type_stack <- (WithType.with_type t) :: ctx.with_type_stack;
 				let e = match ctx.g.do_macro ctx MExpr c.cl_path cf.cf_name [e] p with
 				let e = match ctx.g.do_macro ctx MExpr c.cl_path cf.cf_name [e] p with
-					| Some e -> type_expr ctx e (WithType.with_type t)
-					| None ->  type_expr ctx (EConst (Ident "null"),p) WithType.value
+					| MSuccess e -> type_expr ctx e (WithType.with_type t)
+					| _ ->  type_expr ctx (EConst (Ident "null"),p) WithType.value
 				in
 				in
 				ctx.with_type_stack <- List.tl ctx.with_type_stack;
 				ctx.with_type_stack <- List.tl ctx.with_type_stack;
-				let e = try cast_or_unify_raise ctx t e p with Error(Unify _,_,_) -> raise Not_found in
+				let e = try cast_or_unify_raise ctx t e p with Error { err_message = Unify _ } -> raise Not_found in
 				f();
 				f();
 				e
 				e
 			| _ -> die "" __LOC__
 			| _ -> die "" __LOC__
@@ -38,10 +37,10 @@ and do_check_cast ctx uctx tleft eright p =
 				(try
 				(try
 					Type.unify_custom uctx eright.etype tleft;
 					Type.unify_custom uctx eright.etype tleft;
 				with Unify_error l ->
 				with Unify_error l ->
-					raise (Error (Unify l, eright.epos,0)))
+					raise_error_msg (Unify l) eright.epos)
 			| _ -> ()
 			| _ -> ()
 		end;
 		end;
-		if cf == ctx.curfield || rec_stack_memq cf cast_stack then typing_error "Recursive implicit cast" p;
+		if cf == ctx.curfield || rec_stack_memq cf cast_stack then raise_typing_error "Recursive implicit cast" p;
 		rec_stack_loop cast_stack cf f ()
 		rec_stack_loop cast_stack cf f ()
 	in
 	in
 	let make (a,tl,(tcf,cf)) =
 	let make (a,tl,(tcf,cf)) =
@@ -89,7 +88,9 @@ and do_check_cast ctx uctx tleft eright p =
 					end
 					end
 				| TInst(c,tl), TFun _ when has_class_flag c CFunctionalInterface ->
 				| TInst(c,tl), TFun _ when has_class_flag c CFunctionalInterface ->
 					let cf = ctx.g.functional_interface_lut#find c.cl_path in
 					let cf = ctx.g.functional_interface_lut#find c.cl_path in
-					unify_raise_custom uctx eright.etype (apply_params c.cl_params tl cf.cf_type) p;
+					let map = apply_params c.cl_params tl in
+					let monos = Monomorph.spawn_constrained_monos map cf.cf_params in
+					unify_raise_custom uctx eright.etype (map (apply_params cf.cf_params monos cf.cf_type)) p;
 					eright
 					eright
 				| _ ->
 				| _ ->
 					raise Not_found
 					raise Not_found
@@ -112,18 +113,19 @@ and cast_or_unify_raise ctx ?(uctx=None) tleft eright p =
 and cast_or_unify ctx tleft eright p =
 and cast_or_unify ctx tleft eright p =
 	try
 	try
 		cast_or_unify_raise ctx tleft eright p
 		cast_or_unify_raise ctx tleft eright p
-	with Error (Unify l,p,_) ->
-		raise_or_display ctx l p;
+	with Error ({ err_message = Unify _ } as err) ->
+		raise_or_display_error ctx err;
 		eright
 		eright
 
 
 let prepare_array_access_field ctx a pl cf p =
 let prepare_array_access_field ctx a pl cf p =
 	let monos = List.map (fun _ -> spawn_monomorph ctx p) cf.cf_params in
 	let monos = List.map (fun _ -> spawn_monomorph ctx p) cf.cf_params in
 	let map t = apply_params a.a_params pl (apply_params cf.cf_params monos t) in
 	let map t = apply_params a.a_params pl (apply_params cf.cf_params monos t) in
 	let check_constraints () =
 	let check_constraints () =
-		List.iter2 (fun m tp -> match follow tp.ttp_type with
-			| TInst ({ cl_kind = KTypeParameter constr },_) when constr <> [] ->
+		List.iter2 (fun m ttp -> match get_constraints ttp with
+			| [] ->
+				()
+			| constr ->
 				List.iter (fun tc -> match follow m with TMono _ -> raise (Unify_error []) | _ -> Type.unify m (map tc) ) constr
 				List.iter (fun tc -> match follow m with TMono _ -> raise (Unify_error []) | _ -> Type.unify m (map tc) ) constr
-			| _ -> ()
 		) monos cf.cf_params;
 		) monos cf.cf_params;
 	in
 	in
 	let get_ta() =
 	let get_ta() =
@@ -146,7 +148,7 @@ let find_array_read_access_raise ctx a pl e1 p =
 					let e1 = cast_or_unify_raise ctx ta1 e1 p in
 					let e1 = cast_or_unify_raise ctx ta1 e1 p in
 					check_constraints();
 					check_constraints();
 					cf,tf,r,e1
 					cf,tf,r,e1
-				with Unify_error _ | Error (Unify _,_,_) ->
+				with Unify_error _ | Error { err_message = Unify _ } ->
 					loop cfl
 					loop cfl
 				end
 				end
 			| _ -> loop cfl
 			| _ -> loop cfl
@@ -167,7 +169,7 @@ let find_array_write_access_raise ctx a pl e1 e2  p =
 					let e2 = cast_or_unify_raise ctx ta2 e2 p in
 					let e2 = cast_or_unify_raise ctx ta2 e2 p in
 					check_constraints();
 					check_constraints();
 					cf,tf,r,e1,e2
 					cf,tf,r,e1,e2
-				with Unify_error _ | Error (Unify _,_,_) ->
+				with Unify_error _ | Error { err_message = Unify _ } ->
 					loop cfl
 					loop cfl
 				end
 				end
 			| _ -> loop cfl
 			| _ -> loop cfl
@@ -179,14 +181,14 @@ let find_array_read_access ctx a tl e1 p =
 		find_array_read_access_raise ctx a tl e1 p
 		find_array_read_access_raise ctx a tl e1 p
 	with Not_found ->
 	with Not_found ->
 		let s_type = s_type (print_context()) in
 		let s_type = s_type (print_context()) in
-		typing_error (Printf.sprintf "No @:arrayAccess function for %s accepts argument of %s" (s_type (TAbstract(a,tl))) (s_type e1.etype)) p
+		raise_typing_error (Printf.sprintf "No @:arrayAccess function for %s accepts argument of %s" (s_type (TAbstract(a,tl))) (s_type e1.etype)) p
 
 
 let find_array_write_access ctx a tl e1 e2 p =
 let find_array_write_access ctx a tl e1 e2 p =
 	try
 	try
 		find_array_write_access_raise ctx a tl e1 e2 p
 		find_array_write_access_raise ctx a tl e1 e2 p
 	with Not_found ->
 	with Not_found ->
 		let s_type = s_type (print_context()) in
 		let s_type = s_type (print_context()) in
-		typing_error (Printf.sprintf "No @:arrayAccess function for %s accepts arguments of %s and %s" (s_type (TAbstract(a,tl))) (s_type e1.etype) (s_type e2.etype)) p
+		raise_typing_error (Printf.sprintf "No @:arrayAccess function for %s accepts arguments of %s and %s" (s_type (TAbstract(a,tl))) (s_type e1.etype) (s_type e2.etype)) p
 
 
 let find_multitype_specialization com a pl p =
 let find_multitype_specialization com a pl p =
 	let uctx = default_unification_context in
 	let uctx = default_unification_context in
@@ -202,7 +204,7 @@ let find_multitype_specialization com a pl p =
 					stack := t :: !stack;
 					stack := t :: !stack;
 					match follow t with
 					match follow t with
 					| TAbstract ({ a_path = [],"Class" },_) ->
 					| TAbstract ({ a_path = [],"Class" },_) ->
-						typing_error (Printf.sprintf "Cannot use %s as key type to Map because Class<T> is not comparable on JavaScript" (s_type (print_context()) t1)) p;
+						raise_typing_error (Printf.sprintf "Cannot use %s as key type to Map because Class<T> is not comparable on JavaScript" (s_type (print_context()) t1)) p;
 					| TEnum(en,tl) ->
 					| TEnum(en,tl) ->
 						PMap.iter (fun _ ef -> ignore(loop ef.ef_type)) en.e_constrs;
 						PMap.iter (fun _ ef -> ignore(loop ef.ef_type)) en.e_constrs;
 						Type.map loop t
 						Type.map loop t
@@ -219,16 +221,16 @@ let find_multitype_specialization com a pl p =
 			if List.exists (fun t -> has_mono t) definitive_types then begin
 			if List.exists (fun t -> has_mono t) definitive_types then begin
 				let at = apply_params a.a_params pl a.a_this in
 				let at = apply_params a.a_params pl a.a_this in
 				let st = s_type (print_context()) at in
 				let st = s_type (print_context()) at in
-				typing_error ("Type parameters of multi type abstracts must be known (for " ^ st ^ ")") p
+				raise_typing_error ("Type parameters of multi type abstracts must be known (for " ^ st ^ ")") p
 			end;
 			end;
 			t
 			t
 		with Not_found ->
 		with Not_found ->
 			let at = apply_params a.a_params pl a.a_this in
 			let at = apply_params a.a_params pl a.a_this in
 			let st = s_type (print_context()) at in
 			let st = s_type (print_context()) at in
 			if has_mono at then
 			if has_mono at then
-				typing_error ("Type parameters of multi type abstracts must be known (for " ^ st ^ ")") p
+				raise_typing_error ("Type parameters of multi type abstracts must be known (for " ^ st ^ ")") p
 			else
 			else
-				typing_error ("Abstract " ^ (s_type_path a.a_path) ^ " has no @:to function that accepts " ^ st) p;
+				raise_typing_error ("Abstract " ^ (s_type_path a.a_path) ^ " has no @:to function that accepts " ^ st) p;
 	in
 	in
 	cf, follow m
 	cf, follow m
 
 
@@ -240,7 +242,7 @@ let handle_abstract_casts ctx e =
 					let's construct the underlying type. *)
 					let's construct the underlying type. *)
 				match Abstract.get_underlying_type a pl with
 				match Abstract.get_underlying_type a pl with
 				| TInst(c,tl) as t -> {e with eexpr = TNew(c,tl,el); etype = t}
 				| TInst(c,tl) as t -> {e with eexpr = TNew(c,tl,el); etype = t}
-				| _ -> typing_error ("Cannot construct " ^ (s_type (print_context()) (TAbstract(a,pl)))) e.epos
+				| _ -> raise_typing_error ("Cannot construct " ^ (s_type (print_context()) (TAbstract(a,pl)))) e.epos
 			end else begin
 			end else begin
 				(* a TNew of an abstract implementation is only generated if it is a multi type abstract *)
 				(* a TNew of an abstract implementation is only generated if it is a multi type abstract *)
 				let cf,m = find_multitype_specialization ctx.com a pl e.epos in
 				let cf,m = find_multitype_specialization ctx.com a pl e.epos in

+ 168 - 129
src/context/common.ml

@@ -20,6 +20,7 @@ open Extlib_leftovers
 open Ast
 open Ast
 open Type
 open Type
 open Globals
 open Globals
+open Lookup
 open Define
 open Define
 open NativeLibraries
 open NativeLibraries
 open Warning
 open Warning
@@ -168,39 +169,48 @@ type platform_config = {
 }
 }
 
 
 class compiler_callbacks = object(self)
 class compiler_callbacks = object(self)
-	val mutable before_typer_create = [];
-	val mutable after_init_macros = [];
+	val before_typer_create = ref [];
+	val after_init_macros = ref [];
 	val mutable after_typing = [];
 	val mutable after_typing = [];
-	val mutable before_save = [];
-	val mutable after_save = [];
-	val mutable after_filters = [];
-	val mutable after_generation = [];
+	val before_save = ref [];
+	val after_save = ref [];
+	val after_filters = ref [];
+	val after_generation = ref [];
 	val mutable null_safety_report = [];
 	val mutable null_safety_report = [];
 
 
 	method add_before_typer_create (f : unit -> unit) : unit =
 	method add_before_typer_create (f : unit -> unit) : unit =
-		before_typer_create <- f :: before_typer_create
+		before_typer_create := f :: !before_typer_create
 
 
 	method add_after_init_macros (f : unit -> unit) : unit =
 	method add_after_init_macros (f : unit -> unit) : unit =
-		after_init_macros <- f :: after_init_macros
+		after_init_macros := f :: !after_init_macros
 
 
 	method add_after_typing (f : module_type list -> unit) : unit =
 	method add_after_typing (f : module_type list -> unit) : unit =
 		after_typing <- f :: after_typing
 		after_typing <- f :: after_typing
 
 
 	method add_before_save (f : unit -> unit) : unit =
 	method add_before_save (f : unit -> unit) : unit =
-		before_save <- f :: before_save
+		before_save := f :: !before_save
 
 
 	method add_after_save (f : unit -> unit) : unit =
 	method add_after_save (f : unit -> unit) : unit =
-		after_save <- f :: after_save
+		after_save := f :: !after_save
 
 
 	method add_after_filters (f : unit -> unit) : unit =
 	method add_after_filters (f : unit -> unit) : unit =
-		after_filters <- f :: after_filters
+		after_filters := f :: !after_filters
 
 
 	method add_after_generation (f : unit -> unit) : unit =
 	method add_after_generation (f : unit -> unit) : unit =
-		after_generation <- f :: after_generation
+		after_generation := f :: !after_generation
 
 
 	method add_null_safety_report (f : (string*pos) list -> unit) : unit =
 	method add_null_safety_report (f : (string*pos) list -> unit) : unit =
 		null_safety_report <- f :: null_safety_report
 		null_safety_report <- f :: null_safety_report
 
 
+	method run handle_error r =
+		match !r with
+		| [] ->
+			()
+		| l ->
+			r := [];
+			List.iter (fun f -> try f() with Error.Error err -> handle_error err) (List.rev l);
+			self#run handle_error r
+
 	method get_before_typer_create = before_typer_create
 	method get_before_typer_create = before_typer_create
 	method get_after_init_macros = after_init_macros
 	method get_after_init_macros = after_init_macros
 	method get_after_typing = after_typing
 	method get_after_typing = after_typing
@@ -224,7 +234,7 @@ class file_keys = object(self)
 end
 end
 
 
 type shared_display_information = {
 type shared_display_information = {
-	mutable diagnostics_messages : (string * pos * MessageKind.t * MessageSeverity.t) list;
+	mutable diagnostics_messages : diagnostic list;
 }
 }
 
 
 type display_information = {
 type display_information = {
@@ -247,7 +257,6 @@ type json_api = {
 type compiler_stage =
 type compiler_stage =
 	| CCreated          (* Context was just created *)
 	| CCreated          (* Context was just created *)
 	| CInitialized      (* Context was initialized (from CLI args and such). *)
 	| CInitialized      (* Context was initialized (from CLI args and such). *)
-	| CTyperCreated     (* The typer context was just created. *)
 	| CInitMacrosStart  (* Init macros are about to run. *)
 	| CInitMacrosStart  (* Init macros are about to run. *)
 	| CInitMacrosDone   (* Init macros did run - at this point the signature is locked. *)
 	| CInitMacrosDone   (* Init macros did run - at this point the signature is locked. *)
 	| CTypingDone       (* The typer is done - at this point com.types/modules/main is filled. *)
 	| CTypingDone       (* The typer is done - at this point com.types/modules/main is filled. *)
@@ -262,71 +271,67 @@ type compiler_stage =
 	| CGenerationStart  (* Generation is about to begin. *)
 	| CGenerationStart  (* Generation is about to begin. *)
 	| CGenerationDone   (* Generation just finished. *)
 	| CGenerationDone   (* Generation just finished. *)
 
 
+let s_compiler_stage = function
+	| CCreated          -> "CCreated"
+	| CInitialized      -> "CInitialized"
+	| CInitMacrosStart  -> "CInitMacrosStart"
+	| CInitMacrosDone   -> "CInitMacrosDone"
+	| CTypingDone       -> "CTypingDone"
+	| CFilteringStart   -> "CFilteringStart"
+	| CAnalyzerStart    -> "CAnalyzerStart"
+	| CAnalyzerDone     -> "CAnalyzerDone"
+	| CSaveStart        -> "CSaveStart"
+	| CSaveDone         -> "CSaveDone"
+	| CDceStart         -> "CDceStart"
+	| CDceDone          -> "CDceDone"
+	| CFilteringDone    -> "CFilteringDone"
+	| CGenerationStart  -> "CGenerationStart"
+	| CGenerationDone   -> "CGenerationDone"
+
 type report_mode =
 type report_mode =
 	| RMNone
 	| RMNone
-	| RMDiagnostics of Path.UniqueKey.t list
+	| RMLegacyDiagnostics of (Path.UniqueKey.t list)
+	| RMDiagnostics of (Path.UniqueKey.t list)
 	| RMStatistics
 	| RMStatistics
 
 
-class virtual ['key,'value] lookup = object(self)
-	method virtual add : 'key -> 'value -> unit
-	method virtual remove : 'key -> unit
-	method virtual find : 'key -> 'value
-	method virtual iter : ('key -> 'value -> unit) -> unit
-	method virtual fold : 'acc . ('key -> 'value -> 'acc -> 'acc) -> 'acc -> 'acc
-	method virtual mem : 'key -> bool
-	method virtual clear : unit
-end
-
-class ['key,'value] pmap_lookup = object(self)
-	inherit ['key,'value] lookup
-	val mutable lut : ('key,'value) PMap.t = PMap.empty
-
-	method add (key : 'key) (value : 'value) =
-		lut <- PMap.add key value lut
-
-	method remove (key : 'key) =
-		lut <- PMap.remove key lut
-
-	method find (key : 'key) : 'value =
-		PMap.find key lut
-
-	method iter (f : 'key -> 'value -> unit) =
-		PMap.iter f lut
-
-	method fold : 'acc . ('key -> 'value -> 'acc -> 'acc) -> 'acc -> 'acc = fun f acc ->
-		PMap.foldi f lut acc
+class module_lut = object(self)
+	inherit [path,module_def] hashtbl_lookup as super
 
 
-	method mem (key : 'key) =
-		PMap.mem key lut
+	val type_lut : (path,path) lookup = new hashtbl_lookup
 
 
-	method clear =
-		lut <- PMap.empty
-end
-
-class ['key,'value] hashtbl_lookup = object(self)
-	inherit ['key,'value] lookup
-	val lut : ('key,'value) Hashtbl.t = Hashtbl.create 0
-
-	method add (key : 'key) (value : 'value) =
-		Hashtbl.replace lut key value
-
-	method remove (key : 'key) =
-		Hashtbl.remove lut key
+	method add_module_type (m : module_def) (mt : module_type) =
+		let t = t_infos mt in
+		try
+			let path2 = type_lut#find t.mt_path in
+			let p = t.mt_pos in
+			if m.m_path <> path2 && String.lowercase_ascii (s_type_path path2) = String.lowercase_ascii (s_type_path m.m_path) then Error.raise_typing_error ("Module " ^ s_type_path path2 ^ " is loaded with a different case than " ^ s_type_path m.m_path) p;
+			let m2 = self#find path2 in
+			let hex1 = Digest.to_hex m.m_extra.m_sign in
+			let hex2 = Digest.to_hex m2.m_extra.m_sign in
+			let s = if hex1 = hex2 then hex1 else Printf.sprintf "was %s, is %s" hex2 hex1 in
+			Error.raise_typing_error (Printf.sprintf "Type name %s is redefined from module %s (%s)" (s_type_path t.mt_path)  (s_type_path path2) s) p
+		with Not_found ->
+			type_lut#add t.mt_path m.m_path
 
 
-	method find (key : 'key) : 'value =
-		Hashtbl.find lut key
+	method! add (path : path) (m : module_def) =
+		super#add path m;
+		List.iter (fun mt -> self#add_module_type m mt) m.m_types
 
 
-	method iter (f : 'key -> 'value -> unit) =
-		Hashtbl.iter f lut
+	method! remove (path : path) =
+		try
+			List.iter (fun mt -> type_lut#remove (t_path mt)) (self#find path).m_types;
+			super#remove path;
+		with Not_found ->
+			()
 
 
-	method fold : 'acc . ('key -> 'value -> 'acc -> 'acc) -> 'acc -> 'acc = fun f acc ->
-		Hashtbl.fold f lut acc
+	method find_by_type (path : path) =
+		self#find (type_lut#find path)
 
 
-	method mem (key : 'key) =
-		Hashtbl.mem lut key
+	method! clear =
+		super#clear;
+		type_lut#clear
 
 
-	method clear =
-		Hashtbl.clear lut
+	method get_type_lut = type_lut
 end
 end
 
 
 type context = {
 type context = {
@@ -354,8 +359,9 @@ type context = {
 	(* communication *)
 	(* communication *)
 	mutable print : string -> unit;
 	mutable print : string -> unit;
 	mutable error : ?depth:int -> string -> pos -> unit;
 	mutable error : ?depth:int -> string -> pos -> unit;
-	mutable info : ?depth:int -> string -> pos -> unit;
-	mutable warning : ?depth:int -> warning -> Warning.warning_option list list -> string -> pos -> unit;
+	mutable error_ext : Error.error -> unit;
+	mutable info : ?depth:int -> ?from_macro:bool -> string -> pos -> unit;
+	mutable warning : ?depth:int -> ?from_macro:bool -> warning -> Warning.warning_option list list -> string -> pos -> unit;
 	mutable warning_options : Warning.warning_option list list;
 	mutable warning_options : Warning.warning_option list list;
 	mutable get_messages : unit -> compiler_message list;
 	mutable get_messages : unit -> compiler_message list;
 	mutable filter_messages : (compiler_message -> bool) -> unit;
 	mutable filter_messages : (compiler_message -> bool) -> unit;
@@ -369,19 +375,20 @@ type context = {
 	mutable user_metas : (string, Meta.user_meta) Hashtbl.t;
 	mutable user_metas : (string, Meta.user_meta) Hashtbl.t;
 	mutable get_macros : unit -> context option;
 	mutable get_macros : unit -> context option;
 	(* typing state *)
 	(* typing state *)
+	mutable global_metadata : (string list * metadata_entry * (bool * bool * bool)) list;
 	shared : shared_context;
 	shared : shared_context;
 	display_information : display_information;
 	display_information : display_information;
 	file_lookup_cache : (string,string option) lookup;
 	file_lookup_cache : (string,string option) lookup;
 	file_keys : file_keys;
 	file_keys : file_keys;
+	mutable file_contents : (Path.UniqueKey.t * string option) list;
 	readdir_cache : (string * string,(string array) option) lookup;
 	readdir_cache : (string * string,(string array) option) lookup;
 	parser_cache : (string,(type_def * pos) list) lookup;
 	parser_cache : (string,(type_def * pos) list) lookup;
 	module_to_file : (path,string) lookup;
 	module_to_file : (path,string) lookup;
 	cached_macros : (path * string,(((string * bool * t) list * t * tclass * Type.tclass_field) * module_def)) lookup;
 	cached_macros : (path * string,(((string * bool * t) list * t * tclass * Type.tclass_field) * module_def)) lookup;
 	stored_typed_exprs : (int, texpr) lookup;
 	stored_typed_exprs : (int, texpr) lookup;
 	overload_cache : ((path * string),(Type.t * tclass_field) list) lookup;
 	overload_cache : ((path * string),(Type.t * tclass_field) list) lookup;
-	module_lut : (path,module_def) lookup;
+	module_lut : module_lut;
 	module_nonexistent_lut : (path,bool) lookup;
 	module_nonexistent_lut : (path,bool) lookup;
-	type_to_module : (path,path) lookup;
 	mutable has_error : bool;
 	mutable has_error : bool;
 	pass_debug_messages : string DynArray.t;
 	pass_debug_messages : string DynArray.t;
 	(* output *)
 	(* output *)
@@ -393,7 +400,7 @@ type context = {
 	mutable resources : (string,string) Hashtbl.t;
 	mutable resources : (string,string) Hashtbl.t;
 	(* target-specific *)
 	(* target-specific *)
 	mutable flash_version : float;
 	mutable flash_version : float;
-	mutable neko_libs : string list;
+	mutable neko_lib_paths : string list;
 	mutable include_files : (string * string) list;
 	mutable include_files : (string * string) list;
 	mutable native_libs : native_libraries;
 	mutable native_libs : native_libraries;
 	mutable net_std : string list;
 	mutable net_std : string list;
@@ -405,14 +412,19 @@ type context = {
 	memory_marker : float array;
 	memory_marker : float array;
 }
 }
 
 
-exception Abort of string * pos
+let enter_stage com stage =
+	(* print_endline (Printf.sprintf "Entering stage %s" (s_compiler_stage stage)); *)
+	com.stage <- stage
 
 
 let ignore_error com =
 let ignore_error com =
 	let b = com.display.dms_error_policy = EPIgnore in
 	let b = com.display.dms_error_policy = EPIgnore in
-	if b then
-		if b then com.has_error <- true;
+	if b then com.has_error <- true;
 	b
 	b
 
 
+let module_warning com m w options msg p =
+	DynArray.add m.m_extra.m_cache_bound_objects (Warning(w,msg,p));
+	com.warning w options msg p
+
 (* Defines *)
 (* Defines *)
 
 
 module Define = Define
 module Define = Define
@@ -443,6 +455,8 @@ let define_value com k v =
 let convert_define k =
 let convert_define k =
 	String.concat "_" (ExtString.String.nsplit k "-")
 	String.concat "_" (ExtString.String.nsplit k "-")
 
 
+let is_next com = defined com HaxeNext
+
 let external_defined ctx k =
 let external_defined ctx k =
 	Define.raw_defined ctx.defines (convert_define k)
 	Define.raw_defined ctx.defines (convert_define k)
 
 
@@ -450,9 +464,9 @@ let external_defined_value ctx k =
 	Define.raw_defined_value ctx.defines (convert_define k)
 	Define.raw_defined_value ctx.defines (convert_define k)
 
 
 let reserved_flags = [
 let reserved_flags = [
-	"true";"false";"null";"cross";"js";"lua";"neko";"flash";"php";"cpp";"cs";"java";"python";
+	"true";"false";"null";"cross";"js";"lua";"neko";"flash";"php";"cpp";"cs";"java";"python";"hl";"hlc";
 	"swc";"macro";"sys";"static";"utf16";"haxe";"haxe_ver"
 	"swc";"macro";"sys";"static";"utf16";"haxe";"haxe_ver"
-	]
+]
 
 
 let reserved_flag_namespaces = ["target"]
 let reserved_flag_namespaces = ["target"]
 
 
@@ -472,16 +486,11 @@ let convert_and_validate k =
 let external_define_value ctx k v =
 let external_define_value ctx k v =
 	raw_define_value ctx.defines (convert_and_validate k) v
 	raw_define_value ctx.defines (convert_and_validate k) v
 
 
-(* TODO: Temporary function until #8690, remove after *)
-let external_define_value_no_check ctx k v =
-	Define.raw_define_value ctx.defines (convert_define k) v
-
 let external_define ctx k =
 let external_define ctx k =
 	Define.raw_define ctx.defines (convert_and_validate k)
 	Define.raw_define ctx.defines (convert_and_validate k)
 
 
-(* TODO: Temporary function until #8690, remove after *)
-let external_define_no_check ctx k =
-	Define.raw_define ctx.defines (convert_define k)
+let external_undefine ctx k =
+	Define.raw_undefine ctx.defines (convert_and_validate k)
 
 
 let defines_for_external ctx =
 let defines_for_external ctx =
 	PMap.foldi (fun k v acc ->
 	PMap.foldi (fun k v acc ->
@@ -507,6 +516,7 @@ let short_platform_name = function
 	| Python -> "py"
 	| Python -> "py"
 	| Hl -> "hl"
 	| Hl -> "hl"
 	| Eval -> "evl"
 	| Eval -> "evl"
+	| CustomTarget n -> "c_" ^ n
 
 
 let stats =
 let stats =
 	{
 	{
@@ -552,6 +562,9 @@ let get_config com =
 	match com.platform with
 	match com.platform with
 	| Cross ->
 	| Cross ->
 		default_config
 		default_config
+	| CustomTarget _ ->
+		(* impossible to reach. see update_platform_config *)
+		raise Exit
 	| Js ->
 	| Js ->
 		let es6 = get_es_version com >= 6 in
 		let es6 = get_es_version com >= 6 in
 		{
 		{
@@ -750,6 +763,10 @@ let get_config com =
 			pf_pad_nulls = true;
 			pf_pad_nulls = true;
 			pf_supports_threads = true;
 			pf_supports_threads = true;
 			pf_supports_atomics = true;
 			pf_supports_atomics = true;
+			pf_scoping = {
+				vs_scope = BlockScope;
+				vs_flags = [NoShadowing]
+			};
 		}
 		}
 	| Eval ->
 	| Eval ->
 		{
 		{
@@ -763,8 +780,7 @@ let get_config com =
 
 
 let memory_marker = [|Unix.time()|]
 let memory_marker = [|Unix.time()|]
 
 
-let create compilation_step cs version args =
-	let m = Type.mk_mono() in
+let create compilation_step cs version args display_mode =
 	let rec com = {
 	let rec com = {
 		compilation_step = compilation_step;
 		compilation_step = compilation_step;
 		cs = cs;
 		cs = cs;
@@ -784,7 +800,7 @@ let create compilation_step cs version args =
 		};
 		};
 		sys_args = args;
 		sys_args = args;
 		debug = false;
 		debug = false;
-		display = DisplayTypes.DisplayMode.create !Parser.display_mode;
+		display = display_mode;
 		verbose = false;
 		verbose = false;
 		foptimize = true;
 		foptimize = true;
 		features = Hashtbl.create 0;
 		features = Hashtbl.create 0;
@@ -800,10 +816,10 @@ let create compilation_step cs version args =
 		file = "";
 		file = "";
 		types = [];
 		types = [];
 		callbacks = new compiler_callbacks;
 		callbacks = new compiler_callbacks;
+		global_metadata = [];
 		modules = [];
 		modules = [];
-		module_lut = new hashtbl_lookup;
+		module_lut = new module_lut;
 		module_nonexistent_lut = new hashtbl_lookup;
 		module_nonexistent_lut = new hashtbl_lookup;
-		type_to_module = new hashtbl_lookup;
 		main = None;
 		main = None;
 		flash_version = 10.;
 		flash_version = 10.;
 		resources = Hashtbl.create 0;
 		resources = Hashtbl.create 0;
@@ -811,7 +827,7 @@ let create compilation_step cs version args =
 		native_libs = create_native_libs();
 		native_libs = create_native_libs();
 		net_path_map = Hashtbl.create 0;
 		net_path_map = Hashtbl.create 0;
 		c_args = [];
 		c_args = [];
-		neko_libs = [];
+		neko_lib_paths = [];
 		include_files = [];
 		include_files = [];
 		js_gen = None;
 		js_gen = None;
 		load_extern_type = [];
 		load_extern_type = [];
@@ -822,24 +838,26 @@ let create compilation_step cs version args =
 		user_defines = Hashtbl.create 0;
 		user_defines = Hashtbl.create 0;
 		user_metas = Hashtbl.create 0;
 		user_metas = Hashtbl.create 0;
 		get_macros = (fun() -> None);
 		get_macros = (fun() -> None);
-		info = (fun ?depth _ _ -> die "" __LOC__);
-		warning = (fun ?depth _ _ _ -> die "" __LOC__);
+		info = (fun ?depth ?from_macro _ _ -> die "" __LOC__);
+		warning = (fun ?depth ?from_macro _ _ _ -> die "" __LOC__);
 		warning_options = [];
 		warning_options = [];
 		error = (fun ?depth _ _ -> die "" __LOC__);
 		error = (fun ?depth _ _ -> die "" __LOC__);
+		error_ext = (fun _ -> die "" __LOC__);
 		get_messages = (fun() -> []);
 		get_messages = (fun() -> []);
 		filter_messages = (fun _ -> ());
 		filter_messages = (fun _ -> ());
 		pass_debug_messages = DynArray.create();
 		pass_debug_messages = DynArray.create();
 		basic = {
 		basic = {
-			tvoid = m;
-			tint = m;
-			tfloat = m;
-			tbool = m;
+			tvoid = mk_mono();
+			tint = mk_mono();
+			tfloat = mk_mono();
+			tbool = mk_mono();
+			tstring = mk_mono();
 			tnull = (fun _ -> die "Could use locate abstract Null<T> (was it redefined?)" __LOC__);
 			tnull = (fun _ -> die "Could use locate abstract Null<T> (was it redefined?)" __LOC__);
-			tstring = m;
 			tarray = (fun _ -> die "Could not locate class Array<T> (was it redefined?)" __LOC__);
 			tarray = (fun _ -> die "Could not locate class Array<T> (was it redefined?)" __LOC__);
 		};
 		};
 		file_lookup_cache = new hashtbl_lookup;
 		file_lookup_cache = new hashtbl_lookup;
 		file_keys = new file_keys;
 		file_keys = new file_keys;
+		file_contents = [];
 		readdir_cache = new hashtbl_lookup;
 		readdir_cache = new hashtbl_lookup;
 		module_to_file = new hashtbl_lookup;
 		module_to_file = new hashtbl_lookup;
 		stored_typed_exprs = new hashtbl_lookup;
 		stored_typed_exprs = new hashtbl_lookup;
@@ -855,7 +873,7 @@ let create compilation_step cs version args =
 	com
 	com
 
 
 let is_diagnostics com = match com.report_mode with
 let is_diagnostics com = match com.report_mode with
-	| RMDiagnostics _ -> true
+	| RMLegacyDiagnostics _ | RMDiagnostics _ -> true
 	| _ -> false
 	| _ -> false
 
 
 let disable_report_mode com =
 let disable_report_mode com =
@@ -870,7 +888,12 @@ let clone com is_macro_context =
 	let t = com.basic in
 	let t = com.basic in
 	{ com with
 	{ com with
 		cache = None;
 		cache = None;
-		basic = { t with tvoid = t.tvoid };
+		basic = { t with
+			tint = mk_mono();
+			tfloat = mk_mono();
+			tbool = mk_mono();
+			tstring = mk_mono();
+		};
 		main_class = None;
 		main_class = None;
 		features = Hashtbl.create 0;
 		features = Hashtbl.create 0;
 		callbacks = new compiler_callbacks;
 		callbacks = new compiler_callbacks;
@@ -890,8 +913,7 @@ let clone com is_macro_context =
 		parser_cache = new hashtbl_lookup;
 		parser_cache = new hashtbl_lookup;
 		module_to_file = new hashtbl_lookup;
 		module_to_file = new hashtbl_lookup;
 		overload_cache = new hashtbl_lookup;
 		overload_cache = new hashtbl_lookup;
-		module_lut = new hashtbl_lookup;
-		type_to_module = new hashtbl_lookup;
+		module_lut = new module_lut;
 	}
 	}
 
 
 let file_time file = Extc.filetime file
 let file_time file = Extc.filetime file
@@ -923,12 +945,23 @@ let flash_version_tag = function
 	| v when v >= 12.0 && float_of_int (int_of_float v) = v -> int_of_float v + 11
 	| v when v >= 12.0 && float_of_int (int_of_float v) = v -> int_of_float v + 11
 	| v -> failwith ("Invalid SWF version " ^ string_of_float v)
 	| v -> failwith ("Invalid SWF version " ^ string_of_float v)
 
 
-let init_platform com pf =
-	com.platform <- pf;
-	let name = platform_name pf in
+let update_platform_config com =
+	match com.platform with
+	| CustomTarget _ ->
+		() (* do nothing, configured with macro api *)
+	| _ ->
+		com.config <- get_config com
+
+let init_platform com =
+	let name = platform_name com.platform in
+	if (com.platform = Flash) && Path.file_extension com.file = "swc" then define com Define.Swc
+	else if (com.platform = Hl) && Path.file_extension com.file = "c" then define com Define.Hlc;
+	(* Set the source header, unless the user has set one already or the platform sets a custom one *)
+	if not (defined com Define.SourceHeader) && (com.platform <> Hl) then
+		define_value com Define.SourceHeader ("Generated by Haxe " ^ s_version_full);
 	let forbid acc p = if p = name || PMap.mem p acc then acc else PMap.add p Forbidden acc in
 	let forbid acc p = if p = name || PMap.mem p acc then acc else PMap.add p Forbidden acc in
 	com.package_rules <- List.fold_left forbid com.package_rules ("jvm" :: (List.map platform_name platforms));
 	com.package_rules <- List.fold_left forbid com.package_rules ("jvm" :: (List.map platform_name platforms));
-	com.config <- get_config com;
+	update_platform_config com;
 	if com.config.pf_static then begin
 	if com.config.pf_static then begin
 		raw_define com "target.static";
 		raw_define com "target.static";
 		define com Define.Static;
 		define com Define.Static;
@@ -949,19 +982,26 @@ let init_platform com pf =
 		raw_define com "target.unicode";
 		raw_define com "target.unicode";
 	end;
 	end;
 	raw_define_value com.defines "target.name" name;
 	raw_define_value com.defines "target.name" name;
-	raw_define com name;
+	raw_define com (match com.platform with | CustomTarget _ -> "custom_target" | _ -> name);
 	if com.config.pf_supports_atomics then begin
 	if com.config.pf_supports_atomics then begin
 		raw_define com "target.atomics"
 		raw_define com "target.atomics"
 	end
 	end
 
 
 let set_platform com pf file =
 let set_platform com pf file =
 	if com.platform <> Cross then failwith "Multiple targets";
 	if com.platform <> Cross then failwith "Multiple targets";
-	init_platform com pf;
-	com.file <- file;
-	if (pf = Flash) && Path.file_extension file = "swc" then define com Define.Swc;
-	(* Set the source header, unless the user has set one already or the platform sets a custom one *)
-	if not (defined com Define.SourceHeader) && (pf <> Hl) then
-		define_value com Define.SourceHeader ("Generated by Haxe " ^ s_version_full)
+	com.platform <- pf;
+	com.file <- file
+
+let set_custom_target com name path =
+	if List.find_opt (fun pf -> (platform_name pf) = name) platforms <> None then
+		raise (Arg.Bad (Printf.sprintf "--custom-target cannot use reserved name %s" name));
+	if String.length name > max_custom_target_len then
+		raise (Arg.Bad (Printf.sprintf "--custom-target name %s exceeds the maximum of %d characters" name max_custom_target_len));
+	let name_regexp = Str.regexp "^[a-zA-Z0-9\\_]+$" in
+	if Str.string_match name_regexp name 0 then
+		set_platform com (CustomTarget name) path
+	else
+		raise (Arg.Bad (Printf.sprintf "--custom-target name %s may only contain alphanumeric or underscore characters" name))
 
 
 let add_feature com f =
 let add_feature com f =
 	Hashtbl.replace com.features f true
 	Hashtbl.replace com.features f true
@@ -1013,12 +1053,13 @@ let allow_package ctx s =
 	with Not_found ->
 	with Not_found ->
 		()
 		()
 
 
-let abort ?depth msg p = raise (Abort (msg,p))
+let abort ?(depth = 0) msg p = raise (Error.Fatal_error (Error.make_error ~depth (Custom msg) p))
 
 
 let platform ctx p = ctx.platform = p
 let platform ctx p = ctx.platform = p
 
 
 let platform_name_macro com =
 let platform_name_macro com =
-	if defined com Define.Macro then "macro" else platform_name com.platform
+	if defined com Define.Macro then "macro"
+	else platform_name com.platform
 
 
 let remove_extension file =
 let remove_extension file =
 	try String.sub file 0 (String.rindex file '.')
 	try String.sub file 0 (String.rindex file '.')
@@ -1078,7 +1119,7 @@ let cache_directory ctx class_path dir f_dir =
 	in
 	in
 	Option.may (Array.iter prepare_file) dir_listing
 	Option.may (Array.iter prepare_file) dir_listing
 
 
-let find_file ctx f =
+let find_file ctx ?(class_path=ctx.class_path) f =
 	try
 	try
 		match ctx.file_lookup_cache#find f with
 		match ctx.file_lookup_cache#find f with
 		| None -> raise Exit
 		| None -> raise Exit
@@ -1113,7 +1154,7 @@ let find_file ctx f =
 						loop (had_empty || p = "") l
 						loop (had_empty || p = "") l
 				end
 				end
 		in
 		in
-		let r = try Some (loop false ctx.class_path) with Not_found -> None in
+		let r = try Some (loop false class_path) with Not_found -> None in
 		ctx.file_lookup_cache#add f r;
 		ctx.file_lookup_cache#add f r;
 		match r with
 		match r with
 		| None -> raise Not_found
 		| None -> raise Not_found
@@ -1217,23 +1258,21 @@ let utf16_to_utf8 str =
 	loop 0;
 	loop 0;
 	Buffer.contents b
 	Buffer.contents b
 
 
-let add_diagnostics_message com msg kind sev =
-	let p = Globals.extract_located_pos msg in
-	let s = Globals.extract_located_msg msg in
+let add_diagnostics_message ?(depth = 0) ?(code = None) com s p kind sev =
 	if sev = MessageSeverity.Error then com.has_error <- true;
 	if sev = MessageSeverity.Error then com.has_error <- true;
 	let di = com.shared.shared_display_information in
 	let di = com.shared.shared_display_information in
-	di.diagnostics_messages <- (s,p,kind,sev) :: di.diagnostics_messages
+	di.diagnostics_messages <- (make_diagnostic ~depth ~code s p kind sev) :: di.diagnostics_messages
 
 
-let located_display_error com ?(depth = 0) msg =
-	if is_diagnostics com then
-		add_diagnostics_message com msg MessageKind.DKCompilerMessage MessageSeverity.Error
-	else
-		com.error (Globals.extract_located_msg msg) (Globals.extract_located_pos msg) ~depth
+let display_error_ext com err =
+	if is_diagnostics com then begin
+		Error.recurse_error (fun depth err ->
+			add_diagnostics_message ~depth com (Error.error_msg err.err_message) err.err_pos MessageKind.DKCompilerMessage MessageSeverity.Error;
+		) err;
+	end else
+		com.error_ext err
 
 
 let display_error com ?(depth = 0) msg p =
 let display_error com ?(depth = 0) msg p =
-	located_display_error com ~depth (Globals.located msg p)
-
-open Printer
+	display_error_ext com (Error.make_error ~depth (Custom msg) p)
 
 
 let dump_path com =
 let dump_path com =
 	Define.defined_value_safe ~default:"dump" com.defines Define.DumpPath
 	Define.defined_value_safe ~default:"dump" com.defines Define.DumpPath

+ 42 - 55
src/context/display/deprecationCheck.ml

@@ -3,37 +3,48 @@ open Type
 open Common
 open Common
 open Ast
 open Ast
 
 
-let curclass = ref null_class
-let curfield = ref null_field
+type deprecation_context = {
+	com        : Common.context;
+	class_meta : metadata_entry list;
+	field_meta : metadata_entry list;
+	curmod     : module_def;
+}
+
+let create_context com = {
+	com = com;
+	class_meta = [];
+	field_meta = [];
+	curmod = null_module;
+}
 
 
 let warned_positions = Hashtbl.create 0
 let warned_positions = Hashtbl.create 0
 
 
-let warn_deprecation com s p_usage =
+let warn_deprecation dctx s p_usage =
 	let pkey p = (p.pfile,p.pmin) in
 	let pkey p = (p.pfile,p.pmin) in
 	if not (Hashtbl.mem warned_positions (pkey p_usage)) then begin
 	if not (Hashtbl.mem warned_positions (pkey p_usage)) then begin
 		Hashtbl.add warned_positions (pkey p_usage) (s,p_usage);
 		Hashtbl.add warned_positions (pkey p_usage) (s,p_usage);
-		if not (is_diagnostics com) then begin
-			let options = Warning.from_meta (!curclass.cl_meta @ !curfield.cf_meta) in
-			com.warning WDeprecated options s p_usage;
+		if not (is_diagnostics dctx.com) then begin
+			let options = Warning.from_meta (dctx.class_meta @ dctx.field_meta) in
+			module_warning dctx.com dctx.curmod WDeprecated options s p_usage;
 		end
 		end
 	end
 	end
 
 
-let print_deprecation_message com meta s p_usage =
+let print_deprecation_message dctx meta s p_usage =
 	let s = match meta with
 	let s = match meta with
 		| _,[EConst(String(s,_)),_],_ -> s
 		| _,[EConst(String(s,_)),_],_ -> s
 		| _ -> Printf.sprintf "Usage of this %s is deprecated" s
 		| _ -> Printf.sprintf "Usage of this %s is deprecated" s
 	in
 	in
-	warn_deprecation com s p_usage
+	warn_deprecation dctx s p_usage
 
 
-let check_meta com meta s p_usage =
+let check_meta dctx meta s p_usage =
 	try
 	try
-		print_deprecation_message com (Meta.get Meta.Deprecated meta) s p_usage;
+		print_deprecation_message dctx (Meta.get Meta.Deprecated meta) s p_usage;
 	with Not_found ->
 	with Not_found ->
 		()
 		()
 
 
 let check_cf com cf p = check_meta com cf.cf_meta "field" p
 let check_cf com cf p = check_meta com cf.cf_meta "field" p
 
 
-let check_class com c p = if c != !curclass then check_meta com c.cl_meta "class" p
+let check_class dctx c p = check_meta dctx c.cl_meta "class" p
 
 
 let check_enum com en p = check_meta com en.e_meta "enum" p
 let check_enum com en p = check_meta com en.e_meta "enum" p
 
 
@@ -83,56 +94,32 @@ let run_on_expr com e =
 	in
 	in
 	expr e
 	expr e
 
 
-let run_on_field com cf =
+let run_on_field dctx cf =
 	match cf.cf_expr with
 	match cf.cf_expr with
-	| None ->
+	| Some e when not (Meta.has Meta.Deprecated cf.cf_meta) ->
+		run_on_expr {dctx with field_meta = cf.cf_meta} e
+	| _ ->
 		()
 		()
-	| Some e ->
-		curfield := cf;
-		run_on_expr com e;
-		curfield := null_field
 
 
 let run com =
 let run com =
+	let dctx = create_context com in
 	List.iter (fun t -> match t with
 	List.iter (fun t -> match t with
-		| TClassDecl c ->
-			curclass := c;
-			(match c.cl_constructor with None -> () | Some cf -> run_on_field com cf);
-			(match c.cl_init with None -> () | Some e -> run_on_expr com e);
-			List.iter (run_on_field com) c.cl_ordered_statics;
-			List.iter (run_on_field com) c.cl_ordered_fields;
-			curclass := null_class;
+		| TClassDecl c when not (Meta.has Meta.Deprecated c.cl_meta) ->
+			let dctx = {dctx with class_meta = c.cl_meta; curmod = c.cl_module} in
+			(match c.cl_constructor with None -> () | Some cf -> run_on_field dctx cf);
+			(match c.cl_init with None -> () | Some e -> run_on_expr dctx e);
+			List.iter (run_on_field dctx) c.cl_ordered_statics;
+			List.iter (run_on_field dctx) c.cl_ordered_fields;
 		| _ ->
 		| _ ->
 			()
 			()
 	) com.types
 	) com.types
 
 
-let if_enabled ?(force=false) com fn =
-	if force || not (defined com Define.NoDeprecationWarnings) then fn()
-
-let warn_deprecation ?(force=false) com s p_usage = if_enabled ~force com (fun() -> warn_deprecation com s p_usage)
-
-let print_deprecation_message ?(force=false) com meta s p_usage = if_enabled ~force com (fun() -> print_deprecation_message com meta s p_usage)
-
-let check_meta ?(force=false) com meta s p_usage = if_enabled ~force com (fun() -> check_meta com meta s p_usage)
-
-let check_cf ?(force=false) com cf p = if_enabled ~force com (fun() -> check_cf com cf p)
-
-let check_class ?(force=false) com c p = if_enabled ~force com (fun() -> check_class com c p)
-
-let check_enum ?(force=false) com en p = if_enabled ~force com (fun() -> check_enum com en p)
-
-let check_ef ?(force=false) com ef p = if_enabled ~force com (fun() -> check_ef com ef p)
-
-let check_typedef ?(force=false) com t p = if_enabled ~force com (fun() -> check_typedef com t p)
-
-let check_module_type ?(force=false) com mt p = if_enabled ~force com (fun() -> check_module_type com mt p)
-
-let run_on_expr ?(force=false) com e = if_enabled ~force com (fun() -> run_on_expr com e)
-
-let run_on_field ?(force=false) com cf = if_enabled ~force com (fun() -> run_on_field com cf)
-
-let run ?(force=false) com = if_enabled ~force com (fun() -> run com)
-
-let check_is com name meta p =
-	()
-	(* if name = "is" && not (Meta.has Meta.Deprecated meta) then
-		warn_deprecation com "Using \"is\" as an identifier is deprecated" p *)
+let check_is com m cl_meta cf_meta name meta p =
+	let dctx = {
+		com = com;
+		class_meta = cl_meta;
+		field_meta = cf_meta;
+		curmod = m;
+	} in
+	if is_next dctx.com && name = "is" && not (Meta.has Meta.Deprecated meta) then
+		warn_deprecation dctx "Using \"is\" as an identifier is deprecated" p

+ 29 - 30
src/context/display/diagnostics.ml

@@ -1,15 +1,16 @@
 open Globals
 open Globals
 open Ast
 open Ast
 open Type
 open Type
-open Typecore
 open Common
 open Common
-open Display
-open DisplayTypes.DisplayMode
 open DisplayTypes
 open DisplayTypes
-open DisplayException
 
 
-let add_removable_code ctx s p prange =
-	ctx.removable_code <- (s,p,prange) :: ctx.removable_code
+let add_replaceable_code ctx reason replacement display_range replace_range =
+	ctx.replaceable_code <- {
+		reason = reason;
+		replacement = replacement;
+		display_range = display_range;
+		replace_range = replace_range;
+	} :: ctx.replaceable_code
 
 
 let error_in_diagnostics_run com p =
 let error_in_diagnostics_run com p =
 	let b = DiagnosticsPrinter.is_diagnostics_file com (com.file_keys#get p.pfile) in
 	let b = DiagnosticsPrinter.is_diagnostics_file com (com.file_keys#get p.pfile) in
@@ -20,33 +21,34 @@ let find_unused_variables com e =
 	let vars = Hashtbl.create 0 in
 	let vars = Hashtbl.create 0 in
 	let pmin_map = Hashtbl.create 0 in
 	let pmin_map = Hashtbl.create 0 in
 	let rec loop e = match e.eexpr with
 	let rec loop e = match e.eexpr with
-		| TVar({v_kind = VUser _} as v,eo) when v.v_name <> "_" ->
+		| TVar({v_kind = VUser origin} as v,eo) when v.v_name <> "_" && not (has_var_flag v VUsedByTyper) ->
 			Hashtbl.add pmin_map e.epos.pmin v;
 			Hashtbl.add pmin_map e.epos.pmin v;
-			let p = match eo with
-				| None -> e.epos
-				| Some e1 ->
-					loop e1;
-					{ e.epos with pmax = e1.epos.pmin }
+			let p,replacement = match eo with
+			| Some e1 when origin <> TVOPatternVariable ->
+				loop e1;
+				{ e.epos with pmax = e1.epos.pmin },""
+			| _ ->
+				e.epos,"_"
 			in
 			in
-			Hashtbl.replace vars v.v_id (v,p);
+			Hashtbl.replace vars v.v_id (v,p,replacement);
 		| TLocal ({v_kind = VUser _} as v) ->
 		| TLocal ({v_kind = VUser _} as v) ->
 			Hashtbl.remove vars v.v_id;
 			Hashtbl.remove vars v.v_id;
 		| _ ->
 		| _ ->
 			Type.iter loop e
 			Type.iter loop e
 	in
 	in
 	loop e;
 	loop e;
-	Hashtbl.iter (fun _ (v,p) ->
+	Hashtbl.iter (fun _ (v,p,replacement) ->
 		let p = match (Hashtbl.find_all pmin_map p.pmin) with [_] -> p | _ -> null_pos in
 		let p = match (Hashtbl.find_all pmin_map p.pmin) with [_] -> p | _ -> null_pos in
-		add_removable_code com "Unused variable" v.v_pos p
+		add_replaceable_code com "Unused variable" replacement v.v_pos p
 	) vars
 	) vars
 
 
 let check_other_things com e =
 let check_other_things com e =
 	let had_effect = ref false in
 	let had_effect = ref false in
 	let no_effect p =
 	let no_effect p =
-		add_diagnostics_message com (located "This code has no effect" p) DKCompilerMessage Warning;
+		add_diagnostics_message com "This code has no effect" p DKCompilerMessage Warning;
 	in
 	in
 	let pointless_compound s p =
 	let pointless_compound s p =
-		add_diagnostics_message com (located (Printf.sprintf "This %s has no effect, but some of its sub-expressions do" s) p) DKCompilerMessage Warning;
+		add_diagnostics_message com (Printf.sprintf "This %s has no effect, but some of its sub-expressions do" s) p DKCompilerMessage Warning;
 	in
 	in
 	let rec compound s el p =
 	let rec compound s el p =
 		let old = !had_effect in
 		let old = !had_effect in
@@ -93,20 +95,22 @@ let check_other_things com e =
 	in
 	in
 	loop true e
 	loop true e
 
 
-let prepare_field dctx com cf = match cf.cf_expr with
+let prepare_field dctx dectx com cf = match cf.cf_expr with
 	| None -> ()
 	| None -> ()
 	| Some e ->
 	| Some e ->
 		find_unused_variables dctx e;
 		find_unused_variables dctx e;
 		check_other_things com e;
 		check_other_things com e;
-		DeprecationCheck.run_on_expr ~force:true com e
+		DeprecationCheck.run_on_expr {dectx with field_meta = cf.cf_meta} e
 
 
 let collect_diagnostics dctx com =
 let collect_diagnostics dctx com =
 	let open CompilationCache in
 	let open CompilationCache in
+	let dectx = DeprecationCheck.create_context com in
 	List.iter (function
 	List.iter (function
 		| TClassDecl c when DiagnosticsPrinter.is_diagnostics_file com (com.file_keys#get c.cl_pos.pfile) ->
 		| TClassDecl c when DiagnosticsPrinter.is_diagnostics_file com (com.file_keys#get c.cl_pos.pfile) ->
-			List.iter (prepare_field dctx com) c.cl_ordered_fields;
-			List.iter (prepare_field dctx com) c.cl_ordered_statics;
-			(match c.cl_constructor with None -> () | Some cf -> prepare_field dctx com cf);
+			let dectx = {dectx with class_meta = c.cl_meta} in
+			List.iter (prepare_field dctx dectx com) c.cl_ordered_fields;
+			List.iter (prepare_field dctx dectx com) c.cl_ordered_statics;
+			(match c.cl_constructor with None -> () | Some cf -> prepare_field dctx dectx com cf);
 		| _ ->
 		| _ ->
 			()
 			()
 	) com.types;
 	) com.types;
@@ -136,14 +140,14 @@ let collect_diagnostics dctx com =
 
 
 let prepare com =
 let prepare com =
 	let dctx = {
 	let dctx = {
-		removable_code = [];
+		replaceable_code = [];
 		import_positions = PMap.empty;
 		import_positions = PMap.empty;
 		dead_blocks = Hashtbl.create 0;
 		dead_blocks = Hashtbl.create 0;
 		diagnostics_messages = [];
 		diagnostics_messages = [];
 		unresolved_identifiers = [];
 		unresolved_identifiers = [];
 		missing_fields = PMap.empty;
 		missing_fields = PMap.empty;
 	} in
 	} in
-	if not (List.exists (fun (_,_,_,sev) -> sev = MessageSeverity.Error) com.shared.shared_display_information.diagnostics_messages) then
+	if not (List.exists (fun diag -> diag.diag_severity = MessageSeverity.Error) com.shared.shared_display_information.diagnostics_messages) then
 		collect_diagnostics dctx com;
 		collect_diagnostics dctx com;
 	let process_modules com =
 	let process_modules com =
 		List.iter (fun m ->
 		List.iter (fun m ->
@@ -177,15 +181,10 @@ let prepare com =
 	dctx.unresolved_identifiers <- com.display_information.unresolved_identifiers;
 	dctx.unresolved_identifiers <- com.display_information.unresolved_identifiers;
 	dctx
 	dctx
 
 
-let secure_generated_code ctx e =
-	(* This causes problems and sucks in general... need a different solution. But I forgot which problem this solved anyway. *)
-	(* mk (TMeta((Meta.Extern,[],e.epos),e)) e.etype e.epos *)
-	e
-
 let print com =
 let print com =
 	let dctx = prepare com in
 	let dctx = prepare com in
 	Json.string_of_json (DiagnosticsPrinter.json_of_diagnostics com dctx)
 	Json.string_of_json (DiagnosticsPrinter.json_of_diagnostics com dctx)
 
 
 let run com =
 let run com =
 	let dctx = prepare com in
 	let dctx = prepare com in
-	dctx
+	dctx

+ 82 - 34
src/context/display/diagnosticsPrinter.ml

@@ -2,17 +2,32 @@ open Globals
 open Common
 open Common
 open Json
 open Json
 open DisplayTypes
 open DisplayTypes
-open DisplayTypes
 open Type
 open Type
 open Genjson
 open Genjson
 open MessageKind
 open MessageKind
 
 
-(* type t = DiagnosticsKind.t * pos *)
+type t = {
+	diag_kind : MessageKind.t;
+	diag_pos : pos;
+	diag_severity : MessageSeverity.t;
+	diag_code : string option;
+	diag_args : Json.t;
+	mutable diag_related_information : (pos * int * string) list;
+}
+
+let make_diagnostic kd p sev code args = {
+	diag_kind = kd;
+	diag_pos = p;
+	diag_severity = sev;
+	diag_code = code;
+	diag_args = args;
+	diag_related_information = [];
+}
 
 
 let is_diagnostics_file com file_key =
 let is_diagnostics_file com file_key =
 	match com.report_mode with
 	match com.report_mode with
-	| RMDiagnostics [] -> true
-	| RMDiagnostics file_keys -> List.exists (fun key' -> file_key = key') file_keys
+	| RMLegacyDiagnostics [] | RMDiagnostics [] -> true
+	| RMLegacyDiagnostics file_keys | RMDiagnostics file_keys -> List.mem file_key file_keys
 	| _ -> false
 	| _ -> false
 
 
 module UnresolvedIdentifierSuggestion = struct
 module UnresolvedIdentifierSuggestion = struct
@@ -30,24 +45,26 @@ open CompletionItem
 open CompletionModuleType
 open CompletionModuleType
 
 
 let json_of_diagnostics com dctx =
 let json_of_diagnostics com dctx =
-	let diag = Hashtbl.create 0 in
-	let add append dk p sev args =
+	let diagnostics = Hashtbl.create 0 in
+	let current = ref None in
+	let add append diag =
+		let p = diag.diag_pos in
 		let file = if p = null_pos then p.pfile else Path.get_real_path p.pfile in
 		let file = if p = null_pos then p.pfile else Path.get_real_path p.pfile in
-		let diag = try
-			Hashtbl.find diag file
+		let fdiag = try
+			Hashtbl.find diagnostics file
 		with Not_found ->
 		with Not_found ->
-			let d = Hashtbl.create 0 in
-			Hashtbl.add diag file d;
+			let d = [] in
+			Hashtbl.add diagnostics file d;
 			d
 			d
 		in
 		in
-		if append || not (Hashtbl.mem diag p) then
-			Hashtbl.add diag p (dk,p,sev,args)
+		if append || (List.find_opt (fun diag -> diag.diag_pos = p) fdiag) = None then
+			Hashtbl.replace diagnostics file (diag :: fdiag)
 	in
 	in
 	let file_keys = new Common.file_keys in
 	let file_keys = new Common.file_keys in
-	let add dk p sev args =
+	let add dk p sev code args =
 		let append = match dk with
 		let append = match dk with
 			| DKUnusedImport
 			| DKUnusedImport
-			| DKRemovableCode
+			| DKReplacableCode
 			| DKDeprecationWarning
 			| DKDeprecationWarning
 			| DKInactiveBlock ->
 			| DKInactiveBlock ->
 				false
 				false
@@ -57,7 +74,11 @@ let json_of_diagnostics com dctx =
 			| DKMissingFields ->
 			| DKMissingFields ->
 				true
 				true
 		in
 		in
-		if p = null_pos || is_diagnostics_file com (file_keys#get p.pfile) then add append dk p sev args
+		if p = null_pos || is_diagnostics_file com (file_keys#get p.pfile) then begin
+			let diag = make_diagnostic dk p sev code args in
+			current := Some diag;
+			add append diag
+		end else current := None
 	in
 	in
 	List.iter (fun (s,p,suggestions) ->
 	List.iter (fun (s,p,suggestions) ->
 		let suggestions = ExtList.List.filter_map (fun (s,item,r) ->
 		let suggestions = ExtList.List.filter_map (fun (s,item,r) ->
@@ -77,10 +98,24 @@ let json_of_diagnostics com dctx =
 					"name",JString s;
 					"name",JString s;
 				])
 				])
 		) suggestions in
 		) suggestions in
-		add DKUnresolvedIdentifier p MessageSeverity.Error (JArray suggestions);
+		add DKUnresolvedIdentifier p MessageSeverity.Error None (JArray suggestions);
 	) dctx.unresolved_identifiers;
 	) dctx.unresolved_identifiers;
-	List.iter (fun (s,p,kind,sev) ->
-		add kind p sev (JString s)
+	List.iter (fun d -> match (d.diag_depth, !current) with
+		| depth, Some diag when depth > 0 ->
+			let lines = ExtString.String.nsplit d.diag_message "\n" in
+			(match lines with
+				| [] -> ()
+				| s :: sub ->
+					let related = List.fold_left (fun acc s -> (d.diag_pos,depth,Error.compl_msg s) :: acc) [] (List.rev sub) in
+					diag.diag_related_information <- List.append diag.diag_related_information ((d.diag_pos,depth,s) :: related);
+			)
+		| 0, _ ->
+			add d.diag_kind d.diag_pos d.diag_severity d.diag_code (JString d.diag_message)
+		| _ ->
+			(* Do not add errors with depth greater than one as top level diagnostic. *)
+			(* This could happen when running diagnostics for a file that is wentioned in *)
+			(* sub errors of a file not included for diagnostics. *)
+			()
 	) (List.rev dctx.diagnostics_messages);
 	) (List.rev dctx.diagnostics_messages);
 	PMap.iter (fun p (mt,mfl) ->
 	PMap.iter (fun p (mt,mfl) ->
 		let jctx = create_context GMMinimum in
 		let jctx = create_context GMMinimum in
@@ -143,23 +178,28 @@ let json_of_diagnostics com dctx =
 			"moduleFile",jstring (Path.UniqueKey.lazy_path (t_infos mt).mt_module.m_extra.m_file);
 			"moduleFile",jstring (Path.UniqueKey.lazy_path (t_infos mt).mt_module.m_extra.m_file);
 			"entries",jarray l
 			"entries",jarray l
 		] in
 		] in
-		add DKMissingFields p MessageSeverity.Error j
+		add DKMissingFields p MessageSeverity.Error None j
 	) dctx.missing_fields;
 	) dctx.missing_fields;
 	(* non-append from here *)
 	(* non-append from here *)
 	begin match Warning.get_mode WDeprecated com.warning_options with
 	begin match Warning.get_mode WDeprecated com.warning_options with
 	| WMEnable ->
 	| WMEnable ->
 		Hashtbl.iter (fun _ (s,p) ->
 		Hashtbl.iter (fun _ (s,p) ->
-			add DKDeprecationWarning p MessageSeverity.Warning (JString s);
+			let wobj = Warning.warning_obj WDeprecated in
+			add DKDeprecationWarning p MessageSeverity.Warning (Some wobj.w_name) (JString s);
 		) DeprecationCheck.warned_positions;
 		) DeprecationCheck.warned_positions;
 	| WMDisable ->
 	| WMDisable ->
 		()
 		()
 	end;
 	end;
 	PMap.iter (fun p r ->
 	PMap.iter (fun p r ->
-		if not !r then add DKUnusedImport p MessageSeverity.Warning (JArray [])
+		if not !r then add DKUnusedImport p MessageSeverity.Warning None (JArray [])
 	) dctx.import_positions;
 	) dctx.import_positions;
-	List.iter (fun (s,p,prange) ->
-		add DKRemovableCode p MessageSeverity.Warning (JObject ["description",JString s;"range",if prange = null_pos then JNull else Genjson.generate_pos_as_range prange])
-	) dctx.removable_code;
+	List.iter (fun rc ->
+		add DKReplacableCode rc.display_range MessageSeverity.Warning None (JObject [
+			"description",JString rc.reason;
+			"newCode",JString rc.replacement;
+			"range",if rc.replace_range = null_pos then JNull else Genjson.generate_pos_as_range rc.replace_range
+		])
+	) dctx.replaceable_code;
 	Hashtbl.iter (fun file ranges ->
 	Hashtbl.iter (fun file ranges ->
 		List.iter (fun (p,e) ->
 		List.iter (fun (p,e) ->
 			let jo = JObject [
 			let jo = JObject [
@@ -167,22 +207,30 @@ let json_of_diagnostics com dctx =
 					"string",JString (Ast.Printer.s_expr e)
 					"string",JString (Ast.Printer.s_expr e)
 				]
 				]
 			] in
 			] in
-			add DKInactiveBlock p MessageSeverity.Hint jo
+			add DKInactiveBlock p MessageSeverity.Hint None jo
 		) ranges
 		) ranges
 	) dctx.dead_blocks;
 	) dctx.dead_blocks;
 	let jl = Hashtbl.fold (fun file diag acc ->
 	let jl = Hashtbl.fold (fun file diag acc ->
-		let jl = Hashtbl.fold (fun _ (dk,p,sev,jargs) acc ->
+		let jl = List.rev_map (fun diag ->
 			(JObject [
 			(JObject [
-				"kind",JInt (MessageKind.to_int dk);
-				"severity",JInt (MessageSeverity.to_int sev);
-				"range",Genjson.generate_pos_as_range p;
-				"args",jargs
-			]) :: acc
-		) diag [] in
+				"kind",JInt (MessageKind.to_int diag.diag_kind);
+				"severity",JInt (MessageSeverity.to_int diag.diag_severity);
+				"range",Genjson.generate_pos_as_range diag.diag_pos;
+				"args",diag.diag_args;
+				"code",(match diag.diag_code with None -> JNull | Some c -> JString c);
+				"relatedInformation",JArray (
+					List.map (fun (pos,depth,msg) -> (JObject [
+						"location",Genjson.generate_pos_as_location pos;
+						"depth",JInt depth;
+						"message",JString msg;
+					])) diag.diag_related_information
+				)
+			])
+		) diag in
 		(JObject [
 		(JObject [
 			"file",if file = "?" then JNull else JString file;
 			"file",if file = "?" then JNull else JString file;
 			"diagnostics",JArray jl
 			"diagnostics",JArray jl
 		]) :: acc
 		]) :: acc
-	) diag [] in
+	) diagnostics [] in
 	let js = JArray jl in
 	let js = JArray jl in
-	js
+	js

+ 5 - 231
src/context/display/display.ml

@@ -2,13 +2,10 @@ open Ast
 open Common
 open Common
 open DisplayTypes
 open DisplayTypes
 open DisplayMode
 open DisplayMode
-open DisplayPosition
 open CompletionItem
 open CompletionItem
-open CompletionResultKind
 open Type
 open Type
 open Typecore
 open Typecore
 open Globals
 open Globals
-open Genjson
 open DisplayPosition
 open DisplayPosition
 open ImportStatus
 open ImportStatus
 
 
@@ -33,233 +30,10 @@ module ReferencePosition = struct
 	let reset () = reference_position := ("",null_pos,SKOther)
 	let reset () = reference_position := ("",null_pos,SKOther)
 end
 end
 
 
-module ExprPreprocessing = struct
-	let find_before_pos dm e =
-		let display_pos = ref (DisplayPosition.display_position#get) in
-		let was_annotated = ref false in
-		let is_annotated,is_completion = match dm with
-			| DMDefault -> (fun p -> not !was_annotated && encloses_position !display_pos p),true
-			| DMHover -> (fun p -> not !was_annotated && encloses_position_gt !display_pos p),false
-			| _ -> (fun p -> not !was_annotated && encloses_position !display_pos p),false
-		in
-		let annotate e dk =
-			was_annotated := true;
-			(EDisplay(e,dk),pos e)
-		in
-		let annotate_marked e = annotate e DKMarked in
-		let mk_null p = annotate_marked ((EConst(Ident "null")),p) in
-		let loop_el el =
-			let pr = DisplayPosition.display_position#with_pos (pos e) in
-			let rec loop el = match el with
-				| [] -> [mk_null pr]
-				| e :: el ->
-					if (pos e).pmin >= pr.pmax then (mk_null pr) :: e :: el
-					else e :: loop el
-			in
-			(* print_endline (Printf.sprintf "%i-%i: PR" pr.pmin pr.pmax);
-			List.iter (fun e ->
-				print_endline (Printf.sprintf "%i-%i: %s" (pos e).pmin (pos e).pmax (Ast.s_expr e));
-			) el; *)
-			match el with
-			| [] -> [mk_null pr]
-			| e :: el ->
-				if (pos e).pmin >= pr.pmax then (mk_null pr) :: e :: el
-				else loop (e :: el)
-		in
-		let in_pattern = ref false in
-		let loop e =
-			(* print_endline (Printf.sprintf "%i-%i: %s" (pos e).pmin (pos e).pmax (Ast.s_expr e)); *)
-			match fst e with
-			| EFunction(FKNamed((_,p),_),_) when is_annotated p && is_completion ->
-				raise Exit
-			| EVars vl when is_annotated (pos e) && is_completion ->
-				let rec loop2 acc mark vl = match vl with
-					| v :: vl ->
-						if mark then
-							loop2 (v :: acc) mark vl
-						else if is_annotated (snd v.ev_name) then
-							(* If the name is the display position, mark the expression *)
-							loop2 (v :: acc) true vl
-						else begin match v.ev_expr with
-							| None ->
-								(* If there is no expression, we don't have to do anything.
-								   Should the display position be on the type-hint, it will
-								   be picked up while loading the type. *)
-								loop2 (v :: acc) mark vl
-							| Some e ->
-								(* Determine the area between the `|` in `var x| = | e`. This is not really
-								   correct because we don't want completion on the left side of the `=`, but
-								   we cannot determine that correctly without knowing its position.
-								   Note: We know `e` itself isn't the display position because this entire
-								   algorithm is bottom-up and it would be marked already if it was. *)
-								let p0 = match v.ev_type with
-									| Some (_,pt) -> pt
-									| None -> snd v.ev_name
-								in
-								let p = {p0 with pmax = (pos e).pmin} in
-								let e = if is_annotated p then annotate_marked e else e in
-								loop2 ({ v with ev_expr = Some e } :: acc) mark vl
-						end
-					| [] ->
-						List.rev acc,mark
-				in
-				let vl,mark = loop2 [] false vl in
-				let e = EVars (List.rev vl),pos e in
-				if !was_annotated then e else raise Exit
-			| EBinop((OpAssign | OpAssignOp _) as op,e1,e2) when is_annotated (pos e) && is_completion ->
-				(* Special case for assign ops: If the expression is marked, but none of its operands are,
-				   we are "probably" interested in the rhs. Like with EVars, this isn't accurate because we
-				   could be on the left side of the `=`. I don't think there's a reason for requesting
-				   completion there though. *)
-				(EBinop(op,e1,annotate_marked e2)),(pos e)
-			| EBinop(OpOr,e1,(EIf(_,(EConst(Ident "null"),_),None),p1)) when is_annotated (pos e) && is_completion && !in_pattern ->
-				(* This HAS TO come from an attempted `case pattern | guard:` completion (issue #7068). *)
-				let p = { p1 with pmin = (pos e1).pmax; pmax = p1.pmin } in
-				EBinop(OpOr,e1,mk_null p),(pos e)
-			| EIf(_,(EConst(Ident "null"),_),None) when is_completion && !in_pattern ->
-				(* This is fine. *)
-				mk_null (pos e)
-			| EBlock [] when is_annotated (pos e) ->
-				annotate e DKStructure
-			| EBlock [EDisplay((EConst(Ident s),pn),DKMarked),_] when is_completion ->
-				let e = EObjectDecl [(s,pn,NoQuotes),(EConst (Ident "null"),null_pos)],(pos e) in
-				annotate e DKStructure
-			| EBlock el when is_annotated (pos e) && is_completion ->
-				let el = loop_el el in
-				EBlock el,(pos e)
-			| ECall(e1,el) when is_annotated (pos e) && is_completion ->
-				let el = loop_el el in
-				ECall(e1,el),(pos e)
-			| ENew((tp,pp),el) when is_annotated (pos e) && is_completion ->
-				if is_annotated pp || pp.pmax >= (DisplayPosition.display_position#get).pmax then
-					annotate_marked e
-				else begin
-					let el = loop_el el in
-					ENew((tp,pp),el),(pos e)
-				end
-			| EArrayDecl el when is_annotated (pos e) && is_completion ->
-				let el = loop_el el in
-				EArrayDecl el,(pos e)
-			| EObjectDecl fl when is_annotated (pos e) && is_completion ->
-				annotate e DKStructure
-			| ESwitch(e1,cases,def) when is_annotated (pos e) ->
-				(* We must be "between" two cases, or at the end of the last case.
-				   Let's find the last case which has a position that is < the display
-				   position and mark it. *)
-				let did_mark = ref false in
-				let mark_case ec p =
-					did_mark := true;
-					let ep = mk_null p in
-					match ec with
-					| Some ec ->
-						let ec = match fst ec with
-							| EBlock el -> (EBlock (el @ [ep]),p)
-							| _ -> (EBlock [ec;ep],p)
-						in
-						Some ec
-					| None ->
-						Some (mk_null p)
-				in
-				let rec loop cases = match cases with
-					| [el,eg,ec,p1] ->
-						let ec = match def with
-						| None when (pos e).pmax > !display_pos.pmin -> (* this is so we don't trigger if we're on the } *)
-							mark_case ec p1 (* no default, must be the last case *)
-						| Some (_,p2) when p1.pmax <= !display_pos.pmin && p2.pmin >= !display_pos.pmax ->
-							mark_case ec p1 (* default is beyond display position, mark *)
-						| _ ->
-							ec (* default contains display position, don't mark *)
-						in
-						[el,eg,ec,p1]
-					| (el1,eg1,ec1,p1) :: (el2,eg2,ec2,p2) :: cases ->
-						if p1.pmax <= !display_pos.pmin && p2.pmin >= !display_pos.pmax then
-							(el1,eg1,mark_case ec1 p1,p1) :: (el2,eg2,ec2,p2) :: cases
-						else
-							(el1,eg1,ec1,p1) :: loop ((el2,eg2,ec2,p2) :: cases)
-					| [] ->
-						[]
-				in
-				let cases = loop cases in
-				let def = if !did_mark then
-					def
-				else match def with
-					| Some(eo,p) when (pos e).pmax > !display_pos.pmin -> Some (mark_case eo p,p)
-					| _ -> def
-				in
-				ESwitch(e1,cases,def),pos e
-			| EDisplay _ ->
-				raise Exit
-			| EMeta((Meta.Markup,_,_),(EConst(String _),p)) when is_annotated p ->
-				annotate_marked e
-			| EConst (String (_,q)) when ((q <> SSingleQuotes) || !Parser.was_auto_triggered) && is_annotated (pos e) && is_completion ->
-				(* TODO: check if this makes any sense *)
-				raise Exit
-			| EConst(Regexp _) when is_annotated (pos e) && is_completion ->
-				raise Exit
-			| EVars vl when is_annotated (pos e) ->
-				(* We only want to mark EVars if we're on a var name. *)
-				if List.exists (fun v -> is_annotated (snd v.ev_name)) vl then
-					annotate_marked e
-				else
-					raise Exit
-			| _ ->
-				if is_annotated (pos e) then
-					annotate_marked e
-				else
-					e
-		in
-		let opt f o =
-			match o with None -> None | Some v -> Some (f v)
-		in
-		let rec map e = match fst e with
-			| ESwitch(e1,cases,def) when is_annotated (pos e) ->
-				let e1 = map e1 in
-				let cases = List.map (fun (el,eg,e,p) ->
-					let old = !in_pattern in
-					in_pattern := true;
-					let el = List.map map el in
-					in_pattern := old;
-					let eg = opt map eg in
-					let e = opt map e in
-					el,eg,e,p
-				) cases in
-				let def = opt (fun (eo,p) -> opt map eo,p) def in
-				loop (ESwitch (e1, cases, def),(pos e))
-			| _ ->
-				loop (Ast.map_expr map e)
-		in
-		try map e with Exit -> e
-
-	let find_display_call e =
-		let found = ref false in
-		let handle_el e el =
-			let call_arg_is_marked () =
-				el = [] || List.exists (fun (e,_) -> match e with EDisplay(_,DKMarked) -> true | _ -> false) el
-			in
-			if not !Parser.was_auto_triggered || call_arg_is_marked () then begin
-			found := true;
-			Parser.mk_display_expr e DKCall
-			end else
-				e
-		in
-		let loop e = match fst e with
-			| ECall(_,el) | ENew(_,el) when not !found && display_position#enclosed_in (pos e) ->
-				handle_el e el
-			| EArray(e1,e2) when not !found && display_position#enclosed_in (pos e2) ->
-				handle_el e [e2]
-			| EDisplay(_,DKCall) ->
-				raise Exit
-			| _ -> e
-		in
-		let rec map e = loop (Ast.map_expr map e) in
-		try map e with Exit -> e
-
-
-	let process_expr com e = match com.display.dms_kind with
-		| DMDefinition | DMTypeDefinition | DMUsage _ | DMImplementation | DMHover | DMDefault -> find_before_pos com.display.dms_kind e
-		| DMSignature -> find_display_call e
-		| _ -> e
-end
+let preprocess_expr com e = match com.display.dms_kind with
+	| DMDefinition | DMTypeDefinition | DMUsage _ | DMImplementation | DMHover | DMDefault -> ExprPreprocessing.find_before_pos com.display.dms_kind e
+	| DMSignature -> ExprPreprocessing.find_display_call e
+	| _ -> e
 
 
 let get_expected_name with_type = match with_type with
 let get_expected_name with_type = match with_type with
 	| WithType.Value (Some src) | WithType.WithType(_,Some src) ->
 	| WithType.Value (Some src) | WithType.WithType(_,Some src) ->
@@ -290,7 +64,7 @@ let sort_fields l with_type tk =
 	in
 	in
 	let l = match with_type with
 	let l = match with_type with
 		| WithType.WithType(t,_) when (match follow t with TMono _ -> false | _ -> true) ->
 		| WithType.WithType(t,_) when (match follow t with TMono _ -> false | _ -> true) ->
-			let rec comp item = match item.ci_type with
+			let comp item = match item.ci_type with
 				| None -> 9
 				| None -> 9
 				| Some (t',_) ->
 				| Some (t',_) ->
 				(* For enum constructors, we consider the return type of the constructor function
 				(* For enum constructors, we consider the return type of the constructor function

+ 18 - 15
src/context/display/displayEmitter.ml

@@ -6,7 +6,6 @@ open DisplayException
 open DisplayTypes
 open DisplayTypes
 open DisplayMode
 open DisplayMode
 open CompletionItem
 open CompletionItem
-open CompletionType
 open ClassFieldOrigin
 open ClassFieldOrigin
 open DisplayTypes.CompletionResultKind
 open DisplayTypes.CompletionResultKind
 open Common
 open Common
@@ -19,6 +18,17 @@ let symbol_of_module_type = function
 	| TTypeDecl td -> SKTypedef td
 	| TTypeDecl td -> SKTypedef td
 	| TAbstractDecl a -> SKAbstract a
 	| TAbstractDecl a -> SKAbstract a
 
 
+let display_alias ctx name t p = match ctx.com.display.dms_kind with
+	| DMDefinition | DMTypeDefinition ->
+		raise_positions [p];
+	| DMUsage _ | DMImplementation ->
+		ReferencePosition.set (name,p,SKOther)
+	| DMHover ->
+		let ct = CompletionType.from_type (get_import_status ctx) t in
+		raise_hover (make_ci_literal name (t,ct)) None p
+	| _ ->
+		()
+
 let display_module_type ctx mt p = match ctx.com.display.dms_kind with
 let display_module_type ctx mt p = match ctx.com.display.dms_kind with
 	| DMDefinition | DMTypeDefinition ->
 	| DMDefinition | DMTypeDefinition ->
 		begin match mt with
 		begin match mt with
@@ -56,20 +66,13 @@ let rec display_type ctx t p =
 			| _ ->
 			| _ ->
 				()
 				()
 
 
-let check_display_type ctx t path =
+let check_display_type ctx t ptp =
 	let add_type_hint () =
 	let add_type_hint () =
-		ctx.g.type_hints <- (ctx.m.curmod.m_extra.m_display,pos path,t) :: ctx.g.type_hints;
+		ctx.g.type_hints <- (ctx.m.curmod.m_extra.m_display,ptp.pos_full,t) :: ctx.g.type_hints;
 	in
 	in
 	let maybe_display_type () =
 	let maybe_display_type () =
-		if ctx.is_display_file && display_position#enclosed_in (pos path) then
-			let p =
-				match path with
-				| ({ tpackage = pack; tname = name; tsub = sub },p) ->
-					let strings = match sub with None -> name :: pack | Some s -> s :: name :: pack in
-					let length = String.length (String.concat "." strings) in
-					{ p with pmax = p.pmin + length }
-			in
-			display_type ctx t p
+		if ctx.is_display_file && display_position#enclosed_in ptp.pos_full then
+			display_type ctx t ptp.pos_path
 	in
 	in
 	add_type_hint();
 	add_type_hint();
 	maybe_display_type()
 	maybe_display_type()
@@ -109,7 +112,7 @@ let display_field ctx origin scope cf p = match ctx.com.display.dms_kind with
 				(* For constructors, we care about the class name so we don't end up looking for "new". *)
 				(* For constructors, we care about the class name so we don't end up looking for "new". *)
 				snd c.cl_path,SKConstructor cf
 				snd c.cl_path,SKConstructor cf
 			| _,(Self (TClassDecl c) | Parent(TClassDecl c)) ->
 			| _,(Self (TClassDecl c) | Parent(TClassDecl c)) ->
-				cf.cf_name,SKField (cf,Some c.cl_path)
+				cf.cf_name,SKField (cf,Some c)
 			| _ ->
 			| _ ->
 				cf.cf_name,SKField (cf,None)
 				cf.cf_name,SKField (cf,None)
 		in
 		in
@@ -165,7 +168,7 @@ let check_display_metadata ctx meta =
 		if display_position#enclosed_in p then display_meta ctx.com meta p;
 		if display_position#enclosed_in p then display_meta ctx.com meta p;
 		List.iter (fun e ->
 		List.iter (fun e ->
 			if display_position#enclosed_in (pos e) then begin
 			if display_position#enclosed_in (pos e) then begin
-				let e = ExprPreprocessing.process_expr ctx.com e in
+				let e = preprocess_expr ctx.com e in
 				delay ctx PTypeField (fun _ -> ignore(type_expr ctx e WithType.value));
 				delay ctx PTypeField (fun _ -> ignore(type_expr ctx e WithType.value));
 			end
 			end
 		) args
 		) args
@@ -192,4 +195,4 @@ let check_field_modifiers ctx c cf override display_modifier =
 			) missing_fields [] in
 			) missing_fields [] in
 			let l = sort_fields l NoValue TKOverride in
 			let l = sort_fields l NoValue TKOverride in
 			raise_fields l CROverride (make_subject (Some cf.cf_name) cf.cf_name_pos)
 			raise_fields l CROverride (make_subject (Some cf.cf_name) cf.cf_name_pos)
-		| _ -> ()
+		| _ -> ()

+ 8 - 8
src/context/display/displayException.ml

@@ -23,9 +23,9 @@ let max_completion_items = ref 0
 let filter_somehow ctx items kind subj =
 let filter_somehow ctx items kind subj =
 	let subject = match subj.s_name with
 	let subject = match subj.s_name with
 		| None -> ""
 		| None -> ""
-		| Some name-> String.lowercase name
+		| Some name-> ExtString.String.lowercase name
 	in
 	in
-	let subject_length = String.length subject in
+	let subject_length = ExtString.String.length subject in
 	let determine_cost s =
 	let determine_cost s =
 		let get_initial_cost o =
 		let get_initial_cost o =
 			if o = 0 then
 			if o = 0 then
@@ -33,7 +33,7 @@ let filter_somehow ctx items kind subj =
 			else begin
 			else begin
 				(* Consider `.` as anchors and determine distance from closest one. Penalize starting distance by factor 2. *)
 				(* Consider `.` as anchors and determine distance from closest one. Penalize starting distance by factor 2. *)
 				try
 				try
-					let last_anchor = String.rindex_from s o '.' in
+					let last_anchor = ExtString.String.rindex_from s o '.' in
 					(o - (last_anchor + 1)) * 2
 					(o - (last_anchor + 1)) * 2
 				with Not_found ->
 				with Not_found ->
 					o * 2
 					o * 2
@@ -54,12 +54,12 @@ let filter_somehow ctx items kind subj =
 				let o',new_cost = index_from o subject.[i] in
 				let o',new_cost = index_from o subject.[i] in
 				loop (i + 1) o' (cost + new_cost)
 				loop (i + 1) o' (cost + new_cost)
 			end else
 			end else
-				cost + (if o = String.length s - 1 then 0 else 1) (* Slightly penalize for not-exact matches. *)
+				cost + (if o = ExtString.String.length s - 1 then 0 else 1) (* Slightly penalize for not-exact matches. *)
 		in
 		in
 		if subject_length = 0 then
 		if subject_length = 0 then
 			0
 			0
 		else try
 		else try
-			let o = String.index s subject.[0] in
+			let o = ExtString.String.index s subject.[0] in
 			loop 1 o (get_initial_cost o);
 			loop 1 o (get_initial_cost o);
 		with Not_found | Invalid_argument _ ->
 		with Not_found | Invalid_argument _ ->
 			-1
 			-1
@@ -67,7 +67,7 @@ let filter_somehow ctx items kind subj =
 	let rec loop acc items index =
 	let rec loop acc items index =
 		match items with
 		match items with
 		| item :: items ->
 		| item :: items ->
-			let name = String.lowercase (get_filter_name item) in
+			let name = ExtString.String.lowercase (get_filter_name item) in
 			let cost = determine_cost name in
 			let cost = determine_cost name in
 			let acc = if cost >= 0 then
 			let acc = if cost >= 0 then
 				(item,index,cost) :: acc
 				(item,index,cost) :: acc
@@ -102,8 +102,8 @@ let patch_completion_subject subj =
 	match subj.s_name with
 	match subj.s_name with
 	| Some name ->
 	| Some name ->
 		let delta = p.pmax - p.pmin in
 		let delta = p.pmax - p.pmin in
-		let name = if delta > 0 && delta < String.length name then
-			String.sub name 0 delta
+		let name = if delta > 0 && delta < ExtString.String.length name then
+			ExtString.String.sub name 0 delta
 		else
 		else
 			name
 			name
 		in
 		in

+ 30 - 25
src/context/display/displayFields.ml

@@ -56,10 +56,11 @@ let collect_static_extensions ctx items e p =
 		| TFun((_,_,t) :: args, ret) ->
 		| TFun((_,_,t) :: args, ret) ->
 			begin try
 			begin try
 				let e = TyperBase.unify_static_extension ctx {e with etype = dup e.etype} t p in
 				let e = TyperBase.unify_static_extension ctx {e with etype = dup e.etype} t p in
-				List.iter2 (fun m tp -> match follow tp.ttp_type with
-					| TInst ({ cl_kind = KTypeParameter constr },_) when constr <> [] ->
+				List.iter2 (fun m ttp -> match get_constraints ttp with
+					| [] ->
+						()
+					| constr ->
 						List.iter (fun tc -> unify_raise m (map tc) e.epos) constr
 						List.iter (fun tc -> unify_raise m (map tc) e.epos) constr
-					| _ -> ()
 				) monos f.cf_params;
 				) monos f.cf_params;
 				if not (can_access ctx c f true) || follow e.etype == t_dynamic && follow t != t_dynamic then
 				if not (can_access ctx c f true) || follow e.etype == t_dynamic && follow t != t_dynamic then
 					acc
 					acc
@@ -75,7 +76,7 @@ let collect_static_extensions ctx items e p =
 					let item = make_ci_class_field (CompletionClassField.make f CFSMember origin true) (f.cf_type,ct) in
 					let item = make_ci_class_field (CompletionClassField.make f CFSMember origin true) (f.cf_type,ct) in
 					PMap.add f.cf_name item acc
 					PMap.add f.cf_name item acc
 				end
 				end
-			with Error (Unify _,_,_) | Unify_error _ ->
+			with Error { err_message = Unify _ } | Unify_error _ ->
 				acc
 				acc
 			end
 			end
 		| _ ->
 		| _ ->
@@ -157,9 +158,9 @@ let collect ctx e_ast e dk with_type p =
 				List.fold_left fold_constraints items l
 				List.fold_left fold_constraints items l
 			in
 			in
 			fold_constraints items (Monomorph.classify_down_constraints m)
 			fold_constraints items (Monomorph.classify_down_constraints m)
-		| TInst ({cl_kind = KTypeParameter tl},_) ->
+		| TInst ({cl_kind = KTypeParameter ttp},_) ->
 			(* Type parameters can access the fields of their constraints *)
 			(* Type parameters can access the fields of their constraints *)
-			List.fold_left (fun acc t -> loop acc t) items tl
+			List.fold_left (fun acc t -> loop acc t) items (get_constraints ttp)
 		| TInst(c0,tl) ->
 		| TInst(c0,tl) ->
 			(* For classes, browse the hierarchy *)
 			(* For classes, browse the hierarchy *)
 			let fields = TClass.get_all_fields c0 tl in
 			let fields = TClass.get_all_fields c0 tl in
@@ -228,21 +229,25 @@ let collect ctx e_ast e dk with_type p =
 		| TAnon an ->
 		| TAnon an ->
 			(* @:forwardStatics *)
 			(* @:forwardStatics *)
 			let items = match !(an.a_status) with
 			let items = match !(an.a_status) with
-				| Statics { cl_kind = KAbstractImpl { a_meta = meta; a_this = TInst (c,_) }} when Meta.has Meta.ForwardStatics meta ->
-					let items = List.fold_left (fun acc cf ->
-						if should_access c cf true && is_new_item acc cf.cf_name then begin
-							let origin = Self(TClassDecl c) in
-							let item = make_class_field origin cf in
-							PMap.add cf.cf_name item acc
-						end else
-							acc
-					) items c.cl_ordered_statics in
-					PMap.foldi (fun name item acc ->
-						if is_new_item acc name then
-							PMap.add name item acc
-						else
-							acc
-					) PMap.empty items
+				| ClassStatics { cl_kind = KAbstractImpl { a_meta = meta; a_this}} when Meta.has Meta.ForwardStatics meta ->
+					begin match follow a_this with
+					| TInst (c,_) ->
+						let items = List.fold_left (fun acc cf ->
+							if should_access c cf true && is_new_item acc cf.cf_name then begin
+								let origin = Self(TClassDecl c) in
+								let item = make_class_field origin cf in
+								PMap.add cf.cf_name item acc
+							end else
+								acc
+						) items c.cl_ordered_statics in
+						PMap.foldi (fun name item acc ->
+							if is_new_item acc name then
+								PMap.add name item acc
+							else
+								acc
+						) PMap.empty items
+					| _ -> items
+					end
 				| _ -> items
 				| _ -> items
 			in
 			in
 			(* Anon own fields *)
 			(* Anon own fields *)
@@ -257,7 +262,7 @@ let collect ctx e_ast e dk with_type p =
 						PMap.add name (make_field (CompletionClassField.make cf CFSMember origin true) (cf.cf_type,ct)) acc
 						PMap.add name (make_field (CompletionClassField.make cf CFSMember origin true) (cf.cf_type,ct)) acc
 					in
 					in
 					match !(an.a_status) with
 					match !(an.a_status) with
-						| Statics ({cl_kind = KAbstractImpl a} as c) ->
+						| ClassStatics ({cl_kind = KAbstractImpl a} as c) ->
 							if allow_static_abstract_access c cf then
 							if allow_static_abstract_access c cf then
 								let make = if has_class_field_flag cf CfEnum then
 								let make = if has_class_field_flag cf CfEnum then
 										(make_ci_enum_abstract_field a)
 										(make_ci_enum_abstract_field a)
@@ -267,7 +272,7 @@ let collect ctx e_ast e dk with_type p =
 								add (Self (TAbstractDecl a)) make
 								add (Self (TAbstractDecl a)) make
 							else
 							else
 								acc;
 								acc;
-						| Statics c ->
+						| ClassStatics c ->
 							Display.merge_core_doc ctx (TClassDecl c);
 							Display.merge_core_doc ctx (TClassDecl c);
 							if should_access c cf true then add (Self (TClassDecl c)) make_ci_class_field else acc;
 							if should_access c cf true then add (Self (TClassDecl c)) make_ci_class_field else acc;
 						| EnumStatics en ->
 						| EnumStatics en ->
@@ -373,7 +378,7 @@ let handle_missing_field_raise ctx tthis i mode with_type pfield =
 		| TAbstract(a,_) -> TAbstractDecl a,CFSMember,true
 		| TAbstract(a,_) -> TAbstractDecl a,CFSMember,true
 		| TAnon an ->
 		| TAnon an ->
 			begin match !(an.a_status) with
 			begin match !(an.a_status) with
-			| Statics c -> TClassDecl c,CFSStatic,not (can_access ctx c cf true)
+			| ClassStatics c -> TClassDecl c,CFSStatic,not (can_access ctx c cf true)
 			| EnumStatics en -> TEnumDecl en,CFSStatic,true
 			| EnumStatics en -> TEnumDecl en,CFSStatic,true
 			| AbstractStatics a -> TAbstractDecl a,CFSStatic,true
 			| AbstractStatics a -> TAbstractDecl a,CFSStatic,true
 			| _ -> raise Exit
 			| _ -> raise Exit
@@ -409,4 +414,4 @@ let handle_missing_ident ctx i mode with_type p =
 			handle_missing_field_raise ctx ctx.tthis i mode with_type p
 			handle_missing_field_raise ctx ctx.tthis i mode with_type p
 		with Exit ->
 		with Exit ->
 			()
 			()
-		end
+		end

+ 125 - 13
src/context/display/displayJson.ml

@@ -1,5 +1,4 @@
 open Globals
 open Globals
-open Json.Reader
 open JsonRpc
 open JsonRpc
 open Jsonrpc_handler
 open Jsonrpc_handler
 open Json
 open Json
@@ -60,18 +59,49 @@ class display_handler (jsonrpc : jsonrpc_handler) com (cs : CompilationCache.t)
 			let file = jsonrpc#get_string_param "file" in
 			let file = jsonrpc#get_string_param "file" in
 			Path.get_full_path file
 			Path.get_full_path file
 		) file_input_marker in
 		) file_input_marker in
-		let pos = if requires_offset then jsonrpc#get_int_param "offset" else (-1) in
-		TypeloadParse.current_stdin := jsonrpc#get_opt_param (fun () ->
+		let contents = jsonrpc#get_opt_param (fun () ->
 			let s = jsonrpc#get_string_param "contents" in
 			let s = jsonrpc#get_string_param "contents" in
-			Common.define com Define.DisplayStdin; (* TODO: awkward *)
 			Some s
 			Some s
-		) None;
+		) None in
+
+		let pos = if requires_offset then jsonrpc#get_int_param "offset" else (-1) in
 		Parser.was_auto_triggered := was_auto_triggered;
 		Parser.was_auto_triggered := was_auto_triggered;
-		DisplayPosition.display_position#set {
-			pfile = file;
-			pmin = pos;
-			pmax = pos;
-		}
+
+		if file <> file_input_marker then begin
+			let file_unique = com.file_keys#get file in
+
+			DisplayPosition.display_position#set {
+				pfile = file;
+				pmin = pos;
+				pmax = pos;
+			};
+
+			com.file_contents <- [file_unique, contents];
+		end else begin
+			let file_contents = jsonrpc#get_opt_param (fun () ->
+				jsonrpc#get_opt_param (fun () -> jsonrpc#get_array_param "fileContents") []
+			) [] in
+
+			let file_contents = List.map (fun fc -> match fc with
+				| JObject fl ->
+					let file = jsonrpc#get_string_field "fileContents" "file" fl in
+					let file = Path.get_full_path file in
+					let file_unique = com.file_keys#get file in
+					let contents = jsonrpc#get_opt_param (fun () ->
+						let s = jsonrpc#get_string_field "fileContents" "contents" fl in
+						Some s
+					) None in
+					(file_unique, contents)
+				| _ -> invalid_arg "fileContents"
+			) file_contents in
+
+			let files = (List.map (fun (k, _) -> k) file_contents) in
+			com.file_contents <- file_contents;
+
+			match files with
+			| [] | [_] -> DisplayPosition.display_position#set { pfile = file; pmin = pos; pmax = pos; };
+			| _ -> DisplayPosition.display_position#set_files files;
+		end
 end
 end
 
 
 type handler_context = {
 type handler_context = {
@@ -126,6 +156,16 @@ let handler =
 			hctx.display#set_display_file false true;
 			hctx.display#set_display_file false true;
 			hctx.display#enable_display DMDefinition;
 			hctx.display#enable_display DMDefinition;
 		);
 		);
+		"display/diagnostics", (fun hctx ->
+			hctx.display#set_display_file false false;
+			hctx.display#enable_display DMNone;
+			hctx.com.report_mode <- RMDiagnostics (List.map (fun (f,_) -> f) hctx.com.file_contents);
+
+			(match hctx.com.file_contents with
+			| [file, None] ->
+				hctx.com.display <- { hctx.com.display with dms_display_file_policy = DFPAlso; dms_per_file = true; dms_populate_cache = !ServerConfig.populate_cache_from_display};
+			| _ -> ());
+		);
 		"display/implementation", (fun hctx ->
 		"display/implementation", (fun hctx ->
 			hctx.display#set_display_file false true;
 			hctx.display#set_display_file false true;
 			hctx.display#enable_display (DMImplementation);
 			hctx.display#enable_display (DMImplementation);
@@ -156,6 +196,71 @@ let handler =
 			hctx.display#set_display_file (hctx.jsonrpc#get_bool_param "wasAutoTriggered") true;
 			hctx.display#set_display_file (hctx.jsonrpc#get_bool_param "wasAutoTriggered") true;
 			hctx.display#enable_display DMSignature
 			hctx.display#enable_display DMSignature
 		);
 		);
+		"display/metadata", (fun hctx ->
+			let include_compiler_meta = hctx.jsonrpc#get_bool_param "compiler" in
+			let include_user_meta = hctx.jsonrpc#get_bool_param "user" in
+
+			hctx.com.callbacks#add_after_init_macros (fun () ->
+				let all = Meta.get_meta_list hctx.com.user_metas in
+				let all = List.filter (fun (_, (data:Meta.meta_infos)) ->
+					match data.m_origin with
+					| Compiler when include_compiler_meta -> true
+					| UserDefined _ when include_user_meta -> true
+					| _ -> false
+				) all in
+
+				hctx.send_result (jarray (List.map (fun (t, (data:Meta.meta_infos)) ->
+					let fields = [
+						"name", jstring t;
+						"doc", jstring data.m_doc;
+						"parameters", jarray (List.map jstring data.m_params);
+						"platforms", jarray (List.map (fun p -> jstring (platform_name p)) data.m_platforms);
+						"targets", jarray (List.map (fun u -> jstring (Meta.print_meta_usage u)) data.m_used_on);
+						"internal", jbool data.m_internal;
+						"origin", jstring (match data.m_origin with
+							| Compiler -> "haxe compiler"
+							| UserDefined None -> "user-defined"
+							| UserDefined (Some o) -> o
+						);
+						"links", jarray (List.map jstring data.m_links)
+					] in
+
+					(jobject fields)
+				) all))
+			)
+		);
+		"display/defines", (fun hctx ->
+			let include_compiler_defines = hctx.jsonrpc#get_bool_param "compiler" in
+			let include_user_defines = hctx.jsonrpc#get_bool_param "user" in
+
+			hctx.com.callbacks#add_after_init_macros (fun () ->
+				let all = Define.get_define_list hctx.com.user_defines in
+				let all = List.filter (fun (_, (data:Define.define_infos)) ->
+					match data.d_origin with
+					| Compiler when include_compiler_defines -> true
+					| UserDefined _ when include_user_defines -> true
+					| _ -> false
+				) all in
+
+				hctx.send_result (jarray (List.map (fun (t, (data:Define.define_infos)) ->
+					let fields = [
+						"name", jstring t;
+						"doc", jstring data.d_doc;
+						"parameters", jarray (List.map jstring data.d_params);
+						"platforms", jarray (List.map (fun p -> jstring (platform_name p)) data.d_platforms);
+						"origin", jstring (match data.d_origin with
+							| Compiler -> "haxe compiler"
+							| UserDefined None -> "user-defined"
+							| UserDefined (Some o) -> o
+						);
+						"deprecated", jopt jstring data.d_deprecated;
+						"links", jarray (List.map jstring data.d_links)
+					] in
+
+					(jobject fields)
+				) all))
+			)
+		);
 		"server/readClassPaths", (fun hctx ->
 		"server/readClassPaths", (fun hctx ->
 			hctx.com.callbacks#add_after_init_macros (fun () ->
 			hctx.com.callbacks#add_after_init_macros (fun () ->
 				let cc = hctx.display#get_cs#get_context (Define.get_signature hctx.com.defines) in
 				let cc = hctx.display#get_cs#get_context (Define.get_signature hctx.com.defines) in
@@ -183,13 +288,14 @@ let handler =
 		"server/module", (fun hctx ->
 		"server/module", (fun hctx ->
 			let sign = Digest.from_hex (hctx.jsonrpc#get_string_param "signature") in
 			let sign = Digest.from_hex (hctx.jsonrpc#get_string_param "signature") in
 			let path = Path.parse_path (hctx.jsonrpc#get_string_param "path") in
 			let path = Path.parse_path (hctx.jsonrpc#get_string_param "path") in
-			let cc = hctx.display#get_cs#get_context sign in
+			let cs = hctx.display#get_cs in
+			let cc = cs#get_context sign in
 			let m = try
 			let m = try
 				cc#find_module path
 				cc#find_module path
 			with Not_found ->
 			with Not_found ->
 				hctx.send_error [jstring "No such module"]
 				hctx.send_error [jstring "No such module"]
 			in
 			in
-			hctx.send_result (generate_module cc m)
+			hctx.send_result (generate_module cs cc m)
 		);
 		);
 		"server/type", (fun hctx ->
 		"server/type", (fun hctx ->
 			let sign = Digest.from_hex (hctx.jsonrpc#get_string_param "signature") in
 			let sign = Digest.from_hex (hctx.jsonrpc#get_string_param "signature") in
@@ -272,7 +378,7 @@ let handler =
 			let file = hctx.jsonrpc#get_string_param "file" in
 			let file = hctx.jsonrpc#get_string_param "file" in
 			let fkey = hctx.com.file_keys#get file in
 			let fkey = hctx.com.file_keys#get file in
 			let cs = hctx.display#get_cs in
 			let cs = hctx.display#get_cs in
-			cs#taint_modules fkey "server/invalidate";
+			cs#taint_modules fkey ServerInvalidate;
 			cs#remove_files fkey;
 			cs#remove_files fkey;
 			hctx.send_result jnull
 			hctx.send_result jnull
 		);
 		);
@@ -297,6 +403,12 @@ let handler =
 				l := jstring ("Legacy completion " ^ (if b then "enabled" else "disabled")) :: !l;
 				l := jstring ("Legacy completion " ^ (if b then "enabled" else "disabled")) :: !l;
 				()
 				()
 			) ();
 			) ();
+			hctx.jsonrpc#get_opt_param (fun () ->
+				let b = hctx.jsonrpc#get_bool_param "populateCacheFromDisplay" in
+				ServerConfig.populate_cache_from_display := b;
+				l := jstring ("Compilation cache refill from display " ^ (if b then "enabled" else "disabled")) :: !l;
+				()
+			) ();
 			hctx.send_result (jarray !l)
 			hctx.send_result (jarray !l)
 		);
 		);
 		"server/memory",(fun hctx ->
 		"server/memory",(fun hctx ->

+ 7 - 10
src/context/display/displayTexpr.ml

@@ -4,9 +4,7 @@ open Ast
 open Type
 open Type
 open Typecore
 open Typecore
 open DisplayPosition
 open DisplayPosition
-open CompletionItem
 open CompilationCache
 open CompilationCache
-open ClassFieldOrigin
 
 
 let find_field_by_position sc p =
 let find_field_by_position sc p =
 	List.find (fun cff ->
 	List.find (fun cff ->
@@ -59,14 +57,13 @@ let find_abstract_by_position decls p =
 	loop decls
 	loop decls
 
 
 let actually_check_display_field ctx c cff p =
 let actually_check_display_field ctx c cff p =
-	let context_init = new TypeloadFields.context_init in
-	let cctx = TypeloadFields.create_class_context c context_init p in
+	let cctx = TypeloadFields.create_class_context c p in
 	let ctx = TypeloadFields.create_typer_context_for_class ctx cctx p in
 	let ctx = TypeloadFields.create_typer_context_for_class ctx cctx p in
 	let cff = TypeloadFields.transform_field (ctx,cctx) c cff (ref []) (pos cff.cff_name) in
 	let cff = TypeloadFields.transform_field (ctx,cctx) c cff (ref []) (pos cff.cff_name) in
 	let display_modifier = Typeload.check_field_access ctx cff in
 	let display_modifier = Typeload.check_field_access ctx cff in
-	let fctx = TypeloadFields.create_field_context cctx cff true display_modifier in
+	let fctx = TypeloadFields.create_field_context ctx cctx cff true display_modifier in
 	let cf = TypeloadFields.init_field (ctx,cctx,fctx) cff in
 	let cf = TypeloadFields.init_field (ctx,cctx,fctx) cff in
-	flush_pass ctx PTypeField "check_display_field";
+	flush_pass ctx PTypeField ("check_display_field",(fst c.cl_path @ [snd c.cl_path;fst cff.cff_name]));
 	ignore(follow cf.cf_type)
 	ignore(follow cf.cf_type)
 
 
 let check_display_field ctx sc c cf =
 let check_display_field ctx sc c cf =
@@ -92,8 +89,8 @@ let check_display_class ctx decls c =
 		let sc = find_class_by_position decls c.cl_name_pos in
 		let sc = find_class_by_position decls c.cl_name_pos in
 		ignore(Typeload.type_type_params ctx TPHType c.cl_path (fun() -> c.cl_params) null_pos sc.d_params);
 		ignore(Typeload.type_type_params ctx TPHType c.cl_path (fun() -> c.cl_params) null_pos sc.d_params);
 		List.iter (function
 		List.iter (function
-			| (HExtends(ct,p) | HImplements(ct,p)) when display_position#enclosed_in p ->
-				ignore(Typeload.load_instance ~allow_display:true ctx (ct,p) false)
+			| (HExtends ptp | HImplements ptp) when display_position#enclosed_in ptp.pos_full ->
+				ignore(Typeload.load_instance ~allow_display:true ctx ptp ParamNormal)
 			| _ ->
 			| _ ->
 				()
 				()
 		) sc.d_flags;
 		) sc.d_flags;
@@ -181,7 +178,7 @@ let check_display_file ctx cs =
 			let fkey = DisplayPosition.display_position#get_file_key in
 			let fkey = DisplayPosition.display_position#get_file_key in
 			(* force parsing again : if the completion point have been changed *)
 			(* force parsing again : if the completion point have been changed *)
 			cs#remove_files fkey;
 			cs#remove_files fkey;
-			cs#taint_modules fkey "check_display_file";
+			cs#taint_modules fkey CheckDisplayFile;
 		end
 		end
 	| None ->
 	| None ->
-		()
+		()

+ 6 - 9
src/context/display/displayToplevel.ml

@@ -24,7 +24,6 @@ open Typecore
 open CompletionItem
 open CompletionItem
 open ClassFieldOrigin
 open ClassFieldOrigin
 open DisplayTypes
 open DisplayTypes
-open Genjson
 open Globals
 open Globals
 
 
 (* Merges argument and return types from macro and non-macro context, preferring the one that isn't Dynamic.
 (* Merges argument and return types from macro and non-macro context, preferring the one that isn't Dynamic.
@@ -188,7 +187,7 @@ module CollectionContext = struct
 			Shadowed
 			Shadowed
 		with Not_found ->
 		with Not_found ->
 			let check_wildcard () =
 			let check_wildcard () =
-				List.exists (fun (sl,_) -> (sl,snd path) = path) ctx.ctx.m.wildcard_packages
+				List.exists (fun (sl,_) -> (sl,snd path) = path) ctx.ctx.m.import_resolution#extract_wildcard_packages
 			in
 			in
 			if is_import || (fst path = []) || check_wildcard () then Imported else Unimported
 			if is_import || (fst path = []) || check_wildcard () then Imported else Unimported
 
 
@@ -378,7 +377,7 @@ let collect ctx tk with_type sort =
 				()
 				()
 		in
 		in
 		List.iter enum_ctors ctx.m.curmod.m_types;
 		List.iter enum_ctors ctx.m.curmod.m_types;
-		List.iter enum_ctors (List.map fst ctx.m.module_imports);
+		List.iter enum_ctors (List.map fst ctx.m.import_resolution#extract_type_imports);
 
 
 		(* enum constructors of expected type *)
 		(* enum constructors of expected type *)
 		begin match with_type with
 		begin match with_type with
@@ -415,7 +414,7 @@ let collect ctx tk with_type sort =
 					| _ -> raise Not_found
 					| _ -> raise Not_found
 			with Not_found ->
 			with Not_found ->
 				()
 				()
-		) ctx.m.module_globals;
+		) ctx.m.import_resolution#extract_field_imports;
 
 
 		(* literals *)
 		(* literals *)
 		add (make_ci_literal "null" (tpair t_dynamic)) (Some "null");
 		add (make_ci_literal "null" (tpair t_dynamic)) (Some "null");
@@ -450,17 +449,15 @@ let collect ctx tk with_type sort =
 	end;
 	end;
 
 
 	(* type params *)
 	(* type params *)
-	List.iter (fun tp -> match follow tp.ttp_type with
-		| TInst(c,_) ->
-			add (make_ci_type_param c (tpair tp.ttp_type)) (Some (snd c.cl_path))
-		| _ -> die "" __LOC__
+	List.iter (fun tp ->
+		add (make_ci_type_param tp.ttp_class (tpair tp.ttp_type)) (Some (snd tp.ttp_class.cl_path))
 	) ctx.type_params;
 	) ctx.type_params;
 
 
 	(* module types *)
 	(* module types *)
 	List.iter add_type ctx.m.curmod.m_types;
 	List.iter add_type ctx.m.curmod.m_types;
 
 
 	(* module imports *)
 	(* module imports *)
-	List.iter add_type (List.rev_map fst ctx.m.module_imports); (* reverse! *)
+	List.iter add_type (List.rev_map fst ctx.m.import_resolution#extract_type_imports); (* reverse! *)
 
 
 	(* types from files *)
 	(* types from files *)
 	let cs = ctx.com.cs in
 	let cs = ctx.com.cs in

Энэ ялгаанд хэт олон файл өөрчлөгдсөн тул зарим файлыг харуулаагүй болно