Browse Source

Merge branch 'development' into out_of_curiosity_(don't_freak_out)

# Conflicts:
#	.github/workflows/main.yml
#	libs/ilib/dune
#	libs/ilib/peReader.ml
#	libs/javalib/dune
#	src-json/define.json
#	src/codegen/dotnet.ml
#	src/codegen/gencommon/castDetect.ml
#	src/codegen/gencommon/closuresToClass.ml
#	src/codegen/gencommon/dynamicFieldAccess.ml
#	src/codegen/gencommon/dynamicOperators.ml
#	src/codegen/gencommon/enumToClass.ml
#	src/codegen/gencommon/enumToClass2.ml
#	src/codegen/gencommon/expressionUnwrap.ml
#	src/codegen/gencommon/filterClosures.ml
#	src/codegen/gencommon/fixOverrides.ml
#	src/codegen/gencommon/gencommon.ml
#	src/codegen/gencommon/initFunction.ml
#	src/codegen/gencommon/overloadingConstructor.ml
#	src/codegen/gencommon/realTypeParams.ml
#	src/codegen/gencommon/reflectionCFs.ml
#	src/codegen/gencommon/switchToIf.ml
#	src/codegen/gencommon/unnecessaryCastsRemoval.ml
#	src/codegen/gencommon/unreachableCodeEliminationSynf.ml
#	src/codegen/java.ml
#	src/codegen/javaModern.ml
#	src/context/common.ml
#	src/dune
#	src/filters/filters.ml
#	src/generators/gencs.ml
#	src/generators/genjava.ml
#	src/generators/genshared.ml
#	src/optimization/analyzerTexpr.ml
#	src/typing/matcher.ml
#	src/typing/typeloadCheck.ml
#	src/typing/typeloadFields.ml
#	src/typing/typeloadModule.ml
#	src/typing/typer.ml
#	std/cs/_std/Type.hx
#	tests/server/src/cases/ServerTests.hx
Simon Krajewski 1 year ago
parent
commit
f1acd1a098
100 changed files with 2484 additions and 1570 deletions
  1. 130 98
      .github/workflows/main.yml
  2. 4 0
      .vscode/schemas/define.schema.json
  3. 4 1
      Earthfile
  4. 1 1
      Makefile.win
  5. 2 1
      dune
  6. 1 1
      extra/BUILDING.md
  7. 50 1
      extra/CHANGES.txt
  8. 1 1
      extra/EnvVarUpdate.nsh
  9. 37 38
      extra/ImportAll.hx
  10. 3 4
      extra/github-actions/build-mac.yml
  11. 8 1
      extra/github-actions/build-windows.yml
  12. 0 6
      extra/github-actions/cache-opam.yml
  13. 4 2
      extra/github-actions/install-nsis.yml
  14. 2 7
      extra/github-actions/install-ocaml-libs-windows.yml
  15. 30 8
      extra/github-actions/install-ocaml-windows.yml
  16. 11 7
      extra/github-actions/install-ocaml-windows64.yml
  17. 4 0
      extra/github-actions/test-windows.yml
  18. 49 46
      extra/github-actions/workflows/main.yml
  19. 14 10
      extra/release-checklist.txt
  20. 5 4
      haxe.opam
  21. 3 3
      libs/extc/extc.ml
  22. 21 21
      libs/extc/extc_stubs.c
  23. 2 2
      libs/extc/process_stubs.c
  24. 7 1
      libs/extlib-leftovers/dune
  25. 5 5
      libs/extlib-leftovers/multiArray.ml
  26. 1 1
      libs/extlib-leftovers/uTF8.ml
  27. 7 1
      libs/neko/dune
  28. 2 2
      libs/neko/ncompile.ml
  29. 27 4
      libs/objsize/c_objsize.c
  30. 7 1
      libs/swflib/dune
  31. 1 1
      libs/swflib/swfParser.ml
  32. 1 1
      libs/swflib/swfPic.ml
  33. 7 1
      libs/ttflib/dune
  34. 1 1
      libs/ttflib/tTFParser.ml
  35. 7 1
      libs/ziplib/dune
  36. 8 8
      libs/ziplib/zip.ml
  37. 7 1
      plugins/example/dune
  38. 50 30
      src-json/define.json
  39. 10 0
      src-json/warning.json
  40. 7 1
      src-prebuild/dune
  41. 56 28
      src-prebuild/prebuild.ml
  42. 6 11
      src/codegen/codegen.ml
  43. 85 3
      src/codegen/javaModern.ml
  44. 0 6
      src/codegen/overloads.ml
  45. 3 3
      src/codegen/swfLoader.ml
  46. 5 1
      src/compiler/args.ml
  47. 11 11
      src/compiler/compilationContext.ml
  48. 107 57
      src/compiler/compiler.ml
  49. 3 7
      src/compiler/displayOutput.ml
  50. 10 10
      src/compiler/displayProcessing.ml
  51. 11 9
      src/compiler/generate.ml
  52. 14 3
      src/compiler/helper.ml
  53. 388 0
      src/compiler/messageReporting.ml
  54. 12 14
      src/compiler/retyper.ml
  55. 67 402
      src/compiler/server.ml
  56. 1 1
      src/compiler/serverCompilationContext.ml
  57. 2 1
      src/compiler/serverConfig.ml
  58. 7 1
      src/compiler/serverMessage.ml
  59. 15 16
      src/context/abstractCast.ml
  60. 183 63
      src/context/common.ml
  61. 39 55
      src/context/display/deprecationCheck.ml
  62. 33 35
      src/context/display/diagnostics.ml
  63. 20 17
      src/context/display/diagnosticsPrinter.ml
  64. 1 4
      src/context/display/display.ml
  65. 12 2
      src/context/display/displayEmitter.ml
  66. 8 8
      src/context/display/displayException.ml
  67. 24 20
      src/context/display/displayFields.ml
  68. 9 3
      src/context/display/displayJson.ml
  69. 3 6
      src/context/display/displayTexpr.ml
  70. 4 5
      src/context/display/displayToplevel.ml
  71. 1 1
      src/context/display/documentSymbols.ml
  72. 1 3
      src/context/display/findReferences.ml
  73. 64 58
      src/context/display/importHandling.ml
  74. 1 4
      src/context/display/statistics.ml
  75. 9 7
      src/context/memory.ml
  76. 1 2
      src/context/nativeLibraries.ml
  77. 2 2
      src/context/purityState.ml
  78. 248 0
      src/context/resolution.ml
  79. 1 3
      src/context/sourcemaps.ml
  80. 126 81
      src/context/typecore.ml
  81. 2 4
      src/core/abstract.ml
  82. 5 5
      src/core/ast.ml
  83. 8 2
      src/core/define.ml
  84. 6 4
      src/core/displayTypes.ml
  85. 51 35
      src/core/error.ml
  86. 68 29
      src/core/globals.ml
  87. 3 5
      src/core/inheritDoc.ml
  88. 8 6
      src/core/json/genjson.ml
  89. 6 0
      src/core/meta.ml
  90. 2 2
      src/core/path.ml
  91. 12 3
      src/core/tFunctions.ml
  92. 4 4
      src/core/tOther.ml
  93. 34 96
      src/core/tPrinting.ml
  94. 33 4
      src/core/tType.ml
  95. 9 9
      src/core/tUnification.ml
  96. 79 65
      src/core/texpr.ml
  97. 4 2
      src/core/timer.ml
  98. 3 3
      src/core/warning.ml
  99. 13 5
      src/dune
  100. 0 1
      src/filters/defaultArguments.ml

+ 130 - 98
.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,8 +240,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
@@ -247,6 +259,10 @@ jobs:
     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/') }}-2
+          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,13 +347,14 @@ 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
@@ -351,7 +370,8 @@ jobs:
     strategy:
     strategy:
       fail-fast: false
       fail-fast: false
       matrix:
       matrix:
-        target: [macro, js, hl, cpp, 'jvm', php, python, lua, flash, neko]
+        ocaml: ["4.08.1", "5.0.0"]
+        target: [macro, js, hl, cpp, 'jvm', cs, php, python, lua, flash, neko]
         include:
         include:
           - target: hl
           - target: hl
             APT_PACKAGES: cmake ninja-build libturbojpeg-dev
             APT_PACKAGES: cmake ninja-build libturbojpeg-dev
@@ -365,9 +385,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: linuxBinaries
+          name: linuxBinaries${{ (matrix.ocaml == '5.0.0' && '_ocaml5') || '' }}
+          path: linuxBinaries
 
 
       - name: Install Neko from S3
       - name: Install Neko from S3
         run: |
         run: |
@@ -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
@@ -508,7 +530,7 @@ jobs:
       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/') }}-2
+          key: ${{ runner.os }}-${{ hashFiles('./haxe.opam', './libs/') }}
 
 
       - name: Install Neko from S3
       - name: Install Neko from S3
         run: |
         run: |
@@ -594,7 +616,7 @@ 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
+          ZLIB_VERSION: 1.3
           MBEDTLS_VERSION: 2.25.0
           MBEDTLS_VERSION: 2.25.0
           PCRE2_VERSION: 10.42
           PCRE2_VERSION: 10.42
         run: |
         run: |
@@ -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: |
@@ -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
@@ -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

+ 1 - 1
Makefile.win

@@ -83,7 +83,7 @@ package_choco:
 	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/$(NEKO_VERSION_TAG)/neko-$(NEKO_VERSION)-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)

+ 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)

+ 50 - 1
extra/CHANGES.txt

@@ -1,4 +1,53 @@
-2023-04-06: 4.3.0
+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:
 	New features:
 
 

+ 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 - 4
extra/github-actions/build-mac.yml

@@ -1,7 +1,7 @@
 - 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
+    ZLIB_VERSION: 1.3
     MBEDTLS_VERSION: 2.25.0
     MBEDTLS_VERSION: 2.25.0
     PCRE2_VERSION: 10.42
     PCRE2_VERSION: 10.42
   run: |
   run: |
@@ -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/') }}-2

+ 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: |

+ 49 - 46
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,15 +46,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 }}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
@@ -79,12 +57,22 @@ jobs:
     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,13 +129,14 @@ 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
@@ -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
@@ -175,9 +167,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: linuxBinaries
+          name: linuxBinaries${{ (matrix.ocaml == '5.0.0' && '_ocaml5') || '' }}
+          path: linuxBinaries
 
 
       @import install-neko-unix.yml
       @import install-neko-unix.yml
 
 
@@ -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
@@ -286,7 +280,7 @@ jobs:
       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
@@ -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
@@ -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

+ 14 - 10
extra/release-checklist.txt

@@ -9,22 +9,26 @@
 
 
 - 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

+ 5 - 4
opam → haxe.opam

@@ -19,17 +19,18 @@ 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"
 ]
 ]

+ 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/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) ) {

+ 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)
-)
+)

+ 50 - 30
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",
@@ -168,7 +169,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",
@@ -180,13 +182,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"
 	},
 	},
 	{
 	{
 		"name": "ForceNativeProperty",
 		"name": "ForceNativeProperty",
@@ -197,13 +201,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",
@@ -382,7 +388,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",
@@ -404,7 +411,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",
@@ -432,7 +440,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",
@@ -529,71 +538,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",
@@ -631,24 +651,24 @@
 	},
 	},
 	{
 	{
 		"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": "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"]
 	}
 	}
 ]
 ]

+ 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)
-)
+)

+ 56 - 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
@@ -103,21 +114,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
@@ -164,42 +178,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
 
 
@@ -240,7 +266,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 ^ "
@@ -289,9 +315,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;

+ 6 - 11
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
 
 
@@ -373,7 +372,6 @@ 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)
 			| "pretty" -> dump_types com (Type.s_expr_pretty false "\t" true)
-			| "legacy" -> dump_types com Type.s_expr
 			| "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 (Type.s_expr_ast (not (Common.defined com Define.DumpIgnoreVarIds)) "\t")
@@ -389,7 +387,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.cs#get_context sign)#find_module 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
@@ -416,7 +415,7 @@ 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
 	let mk_texpr = function
-		| TClassDecl c -> mk_anon (ref (Statics c))
+		| TClassDecl c -> mk_anon (ref (ClassStatics c))
 		| TEnumDecl e -> mk_anon (ref (EnumStatics e))
 		| TEnumDecl e -> mk_anon (ref (EnumStatics e))
 		| TAbstractDecl a -> mk_anon (ref (AbstractStatics a))
 		| TAbstractDecl a -> mk_anon (ref (AbstractStatics a))
 		| TTypeDecl _ -> die "" __LOC__
 		| TTypeDecl _ -> die "" __LOC__
@@ -478,10 +477,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

+ 85 - 3
src/codegen/javaModern.ml

@@ -40,9 +40,54 @@ module AccessFlags = struct
 		b land (to_int flag) <> 0
 		b land (to_int flag) <> 0
 end
 end
 
 
-open JClass
+module JDataHoldovers = struct
+	type jwildcard =
+		| WExtends (* + *)
+		| WSuper (* -  *)
+		| WNone
+
+	type jtype_argument =
+		| TType of jwildcard * jsignature
+		| TAny (* * *)
+
+	and jsignature =
+		| TByte (* B *)
+		| TChar (* C *)
+		| TDouble (* D *)
+		| TFloat (* F *)
+		| TInt (* I *)
+		| TLong (* J *)
+		| TShort (* S *)
+		| TBool (* Z *)
+		| TObject of path * jtype_argument list (* L Classname *)
+		| TObjectInner of (string list) * (string * jtype_argument list) list (* L Classname ClassTypeSignatureSuffix *)
+		| TArray of jsignature * int option (* [ *)
+		| TMethod of jmethod_signature (* ( *)
+		| TTypeParameter of string (* T *)
+
+	(* ( jsignature list ) ReturnDescriptor (| V | jsignature) *)
+	and jmethod_signature = jsignature list * jsignature option
+
+	type jtypes = (string * jsignature option * jsignature list) list
+
+	type jannotation = {
+		ann_type : jsignature;
+		ann_elements : (string * jannotation_value) list;
+	}
+
+	and jannotation_value =
+		| ValConst of jsignature * int
+		| ValEnum of jsignature * string (* e *)
+		| ValClass of jsignature (* c *) (* V -> Void *)
+		| ValAnnotation of jannotation (* @ *)
+		| ValArray of jannotation_value list (* [ *)
+end
+
+open JDataHoldovers
 
 
 module JReaderHoldovers = struct
 module JReaderHoldovers = struct
+	open JDataHoldovers
+
 	let rec parse_type_parameter_part s = match s.[0] with
 	let rec parse_type_parameter_part s = match s.[0] with
 		| '*' -> TAny, 1
 		| '*' -> TAny, 1
 		| c ->
 		| c ->
@@ -223,6 +268,43 @@ module JReaderModern = struct
 		name_and_types : (string * string) array;
 		name_and_types : (string * string) array;
 	}
 	}
 
 
+	type jlocal = {
+		ld_start_pc : int;
+		ld_length : int;
+		ld_name : string;
+		ld_descriptor : string;
+		ld_index : int;
+	}
+
+	type jattribute =
+		| AttrCode of jattribute list
+		| AttrDeprecated
+		| AttrLocalVariableTable of jlocal list
+  		| AttrMethodParameters of (string * int) list
+		| AttrSignature of string
+		| AttrVisibleAnnotations of jannotation list
+  		| AttrOther
+
+	type jfield = {
+		jf_name : string;
+		jf_flags : int;
+		jf_types : jtypes;
+		jf_descriptor : jsignature;
+		jf_attributes : jattribute list;
+		jf_code : jattribute list option;
+	}
+
+	type jclass = {
+		jc_path : path;
+		jc_flags : int;
+		jc_super : jsignature;
+		jc_interfaces : jsignature list;
+		jc_types : jtypes;
+		jc_fields : jfield list;
+		jc_methods : jfield list;
+		jc_attributes : jattribute list;
+	}
+
 	let read_constant_pool ch =
 	let read_constant_pool ch =
 		let count = read_ui16 ch in
 		let count = read_ui16 ch in
 		let strings = Array.make count "" in
 		let strings = Array.make count "" in
@@ -340,7 +422,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
@@ -473,7 +555,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

+ 0 - 6
src/codegen/overloads.ml

@@ -219,12 +219,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,_) ->

+ 3 - 3
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
@@ -454,7 +454,7 @@ 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 in
@@ -647,7 +647,7 @@ 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 in

+ 5 - 1
src/compiler/args.ml

@@ -40,7 +40,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-2023 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 = {
@@ -94,6 +94,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

+ 11 - 11
src/compiler/compilationContext.ml

@@ -44,7 +44,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,22 +54,22 @@ 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 = match (extract_located msg) with
-	| [] -> ()
-	| (msg,p) :: tl ->
-		error ~depth ctx msg p;
-		List.iter (fun (msg,p) -> error ~depth:(depth+1) ctx msg p) tl
+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
+

+ 107 - 57
src/compiler/compiler.ml

@@ -4,20 +4,24 @@ open CompilationContext
 
 
 let run_or_diagnose ctx f arg =
 let run_or_diagnose ctx f arg =
 	let com = ctx.com in
 	let com = ctx.com in
-	let handle_diagnostics ?(depth = 0) msg kind =
+	let handle_diagnostics ?(depth = 0) msg p kind =
 		ctx.has_error <- true;
 		ctx.has_error <- true;
-		add_diagnostics_message ~depth com msg kind Error;
+		add_diagnostics_message ~depth com msg p kind Error;
 		DisplayOutput.emit_diagnostics ctx.com
 		DisplayOutput.emit_diagnostics ctx.com
 	in
 	in
 	if is_diagnostics com then begin try
 	if is_diagnostics com then begin try
 			f arg
 			f arg
 		with
 		with
-		| Error.Error(msg,p,depth) ->
-			handle_diagnostics ~depth (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;
+			DisplayOutput.emit_diagnostics ctx.com
 		| 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 arg
@@ -67,14 +71,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
 					| [] -> ()
 					| [] -> ()
@@ -132,13 +137,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
@@ -149,13 +161,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);
-		com.callbacks#run 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 (file,extern) -> NativeLibraryHandler.add_native_lib com file extern) (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
+		Typer.create com macros
 
 
 	let executable_path() =
 	let executable_path() =
 		Extc.executable_path()
 		Extc.executable_path()
@@ -205,8 +216,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
@@ -215,12 +228,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.located_error <- located_error ctx;
-		com.error <- (fun ?(depth = 0) msg p -> com.located_error ~depth (located msg p));
+		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;
@@ -238,35 +251,66 @@ 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;
 	com.stage <- CInitMacrosStart;
-	List.iter (MacroContext.call_init_macro tctx) (List.rev actx.config_macros);
+	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
 	com.stage <- CInitMacrosDone;
 	com.stage <- 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";
-	com.callbacks#run 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;
-	) ();
+	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)
+	);
 	com.stage <- CTypingDone;
 	com.stage <- 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;
 	com.stage <- CFilteringStart;
+	ServerMessage.compiler_stage com;
 	let main, types, modules = run_or_diagnose ctx Finalization.generate tctx in
 	let main, types, modules = run_or_diagnose ctx Finalization.generate tctx in
 	com.main <- main;
 	com.main <- main;
 	com.types <- types;
 	com.types <- types;
@@ -276,33 +320,41 @@ let finalize_typing ctx tctx =
 let filter ctx tctx =
 let filter ctx tctx =
 	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;
+	Filters.run tctx ctx.com.main;
 	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;
 	com.stage <- 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;
 		DisplayProcessing.handle_display_after_finalization ctx tctx display_file_dot_path;
@@ -310,11 +362,13 @@ let compile ctx actx =
 		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;
 		com.stage <- 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;
 		com.stage <- CGenerationDone;
+		ServerMessage.compiler_stage com;
 	end;
 	end;
 	Sys.catch_break false;
 	Sys.catch_break false;
-	com.callbacks#run 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
@@ -329,10 +383,10 @@ try
 with
 with
 	| Abort ->
 	| Abort ->
 		()
 		()
-	| Error.Fatal_error (m,depth) ->
-		located_error ~depth ctx m
-	| Common.Abort msg ->
-		located_error ctx msg
+	| Error.Fatal_error err ->
+		error_ext ctx err
+	| Common.Abort 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) ->
@@ -345,14 +399,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)
+	| Error.Error err ->
+		error_ext ctx err
 	| Generic.Generic_Exception(m,p) ->
 	| Generic.Generic_Exception(m,p) ->
 		error ctx m p
 		error ctx m p
 	| Arg.Bad msg ->
 	| Arg.Bad msg ->
@@ -402,7 +450,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 =
@@ -411,8 +462,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;
@@ -522,8 +572,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 ->

+ 3 - 7
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
@@ -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 = Typer.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 ->
 		end with Common.Abort msg ->
-			located_error ctx msg;
+			error_ext ctx msg;
 			None
 			None
 	in
 	in
 	begin match ctx.com.json_out,fields with
 	begin match ctx.com.json_out,fields with

+ 10 - 10
src/compiler/displayProcessing.ml

@@ -48,7 +48,7 @@ let handle_display_argument_old com file_pos actx =
 			| "diagnostics" ->
 			| "diagnostics" ->
 				com.report_mode <- RMDiagnostics [file_unique];
 				com.report_mode <- RMDiagnostics [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 = DFPAlso; 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 ?depth 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 ?depth 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 ->
 				()
 				()
 		);
 		);
@@ -192,7 +193,7 @@ 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
@@ -209,7 +210,7 @@ let load_display_module_in_macro tctx display_file_dot_path clear = match displa
 					()
 					()
 				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
@@ -354,4 +354,4 @@ let handle_display_after_finalization ctx tctx display_file_dot_path =
 		DisplayOutput.emit_statistics tctx
 		DisplayOutput.emit_statistics tctx
 	| RMNone ->
 	| RMNone ->
 		()
 		()
-	end
+	end

+ 11 - 9
src/compiler/generate.ml

@@ -56,8 +56,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 ->
@@ -85,11 +83,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")

+ 388 - 0
src/compiler/messageReporting.ml

@@ -0,0 +1,388 @@
+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 = {
+	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 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 = Lexer.get_error_pos error_printer cm.cm_pos in
+				(l1, p1, l2, p2, epos, lines)
+			end with Not_found ->
+				(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 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 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
+
+exception ConfigError of string
+
+let get_formatter com ectx def default =
+	let format_mode = Define.defined_value_safe ~default com.defines def in
+	match format_mode with
+		| "pretty" -> compiler_pretty_message_string com ectx
+		| "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 ectx = create_error_context () in
+	ectx.max_lines <- get_max_line ectx.max_lines messages;
+	let message_formatter = get_formatter com ectx Define.MessageReporting "classic" in
+	let lines = List.rev (
+		List.fold_left (fun lines cm -> match (message_formatter cm) with
+			| None -> lines
+			| Some str -> str :: lines
+		) [] messages
+	) in
+	ExtLib.String.join "\n" lines
+
+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 =
+		try get_formatter ctx.com ectx def default
+		with | ConfigError s ->
+			error ctx s null_pos;
+			compiler_message_string
+	in
+
+	let message_formatter = get_formatter ctx.com ectx Define.MessageReporting "classic" in
+	let log_formatter = get_formatter ctx.com ectx 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 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 cm) with
+			| None -> ()
+			| Some str -> on_message cm.cm_severity str
+	) (List.rev ctx.messages);
+
+	if !log_messages then (Option.get !close_logs) ();
+end
+

+ 12 - 14
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
@@ -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

+ 67 - 402
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
@@ -21,7 +19,7 @@ let check_display_flush ctx f_otherwise = match ctx.com.json_out with
 	| None ->
 	| None ->
 		if is_diagnostics ctx.com then begin
 		if is_diagnostics ctx.com then begin
 			List.iter (fun cm ->
 			List.iter (fun cm ->
-				add_diagnostics_message ~depth:cm.cm_depth ctx.com (located cm.cm_message cm.cm_pos) cm.cm_kind cm.cm_severity
+				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);
 			) (List.rev ctx.messages);
 			raise (Completion (Diagnostics.print ctx.com))
 			raise (Completion (Diagnostics.print ctx.com))
 		end else
 		end else
@@ -87,365 +85,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 +118,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 "\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 +288,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 +308,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;
@@ -763,7 +410,10 @@ let add_modules sctx ctx m p =
 				) 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 (Hashtbl.replace com.resources) m.m_extra.m_binded_res;
-				PMap.iter (fun _ m2 -> add_modules (tabs ^ "  ") m0 m2) m.m_extra.m_deps
+				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 +448,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 +543,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 +567,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 +618,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 +715,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);

+ 1 - 1
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

+ 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;

+ 15 - 16
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()
 
 
@@ -19,12 +18,12 @@ let rec make_static_call ctx c cf a pl args t p =
 					| None ->  type_expr ctx (EConst (Ident "null"),p) WithType.value
 					| None ->  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__
 	end else
 	end else
-		Typecore.make_static_call ctx c cf (apply_params a.a_params pl) args t p
+		make_static_abstract_call ctx a pl c cf args p
 
 
 and do_check_cast ctx uctx tleft eright p =
 and do_check_cast ctx uctx tleft eright p =
 	let recurse cf f =
 	let recurse cf f =
@@ -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)) =
@@ -112,8 +111,8 @@ 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 =
@@ -146,7 +145,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 +166,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 +178,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 +201,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 +218,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 +239,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

+ 183 - 63
src/context/common.ml

@@ -201,14 +201,14 @@ class compiler_callbacks = object(self)
 	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 r =
+	method run handle_error r =
 		match !r with
 		match !r with
 		| [] ->
 		| [] ->
 			()
 			()
 		| l ->
 		| l ->
 			r := [];
 			r := [];
-			List.iter (fun f -> f()) (List.rev l);
-			self#run 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
@@ -233,7 +233,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 * int (* depth *)) list;
+	mutable diagnostics_messages : diagnostic list;
 }
 }
 
 
 type display_information = {
 type display_information = {
@@ -256,7 +256,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. *)
@@ -271,6 +270,23 @@ 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
 	| RMDiagnostics of Path.UniqueKey.t list
@@ -363,9 +379,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 located_error : ?depth:int -> located -> 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;
@@ -379,6 +395,7 @@ 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;
@@ -415,12 +432,11 @@ type context = {
 	memory_marker : float array;
 	memory_marker : float array;
 }
 }
 
 
-exception Abort of located
+exception Abort of Error.error
 
 
 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
 
 
 (* Defines *)
 (* Defines *)
@@ -453,6 +469,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)
 
 
@@ -462,7 +480,7 @@ let external_defined_value ctx 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";
 	"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"]
 
 
@@ -482,17 +500,9 @@ 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 defines_for_external ctx =
 let defines_for_external ctx =
 	PMap.foldi (fun k v acc ->
 	PMap.foldi (fun k v acc ->
 		let added_underscore = PMap.add k v acc in
 		let added_underscore = PMap.add k v acc in
@@ -516,6 +526,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 =
 	{
 	{
@@ -561,6 +572,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
 		{
 		{
@@ -723,6 +737,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 ->
 		{
 		{
@@ -773,6 +791,7 @@ 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 hashtbl_lookup;
 		module_nonexistent_lut = new hashtbl_lookup;
 		module_nonexistent_lut = new hashtbl_lookup;
@@ -795,11 +814,11 @@ 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__);
-		located_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();
@@ -897,12 +916,22 @@ 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;
+	(* 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 ("java" :: (List.map platform_name platforms));
-	com.config <- get_config com;
+	com.package_rules <- List.fold_left forbid com.package_rules ("jvm" :: (List.map platform_name platforms));
+	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;
@@ -923,26 +952,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;
-	begin match pf with
-		| Flash ->
-			if Path.file_extension file = "swc" then define com Define.Swc;
-		| Jvm ->
-			raw_define com "java"
-		| _ ->
-			()
-	end;
-	(* 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
@@ -994,13 +1023,13 @@ let allow_package ctx s =
 	with Not_found ->
 	with Not_found ->
 		()
 		()
 
 
-let abort_located ?depth msg = raise (Abort msg)
-let abort ?depth msg p = abort_located ~depth (located msg p)
+let abort ?(depth = 0) msg p = raise (Abort (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 '.')
@@ -1199,33 +1228,27 @@ let utf16_to_utf8 str =
 	loop 0;
 	loop 0;
 	Buffer.contents b
 	Buffer.contents b
 
 
-let add_diagnostics_message ?(depth = 0) com msg kind sev =
+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
-	match (extract_located msg) with
-	| [] -> ()
-	| (s,p) :: [] ->
-		di.diagnostics_messages <- (s,p,kind,sev,depth) :: di.diagnostics_messages
-	| (s,p) :: stack ->
-		let stack_diag = (List.map (fun (s,p) -> (s,p,kind,sev,depth+1)) (List.rev stack)) in
-		di.diagnostics_messages <- stack_diag @ ((s,p,kind,sev,depth) :: di.diagnostics_messages)
-
-let located_display_error com ?(depth = 0) msg =
-	if is_diagnostics com then
-		add_diagnostics_message ~depth com msg MessageKind.DKCompilerMessage MessageSeverity.Error
-	else
-		com.located_error msg ~depth
+	di.diagnostics_messages <- (make_diagnostic ~depth ~code s p kind sev) :: di.diagnostics_messages
 
 
-let display_error com ?(depth = 0) msg p =
-	located_display_error com ~depth (Globals.located msg p)
+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
 
 
-open Printer
+let display_error com ?(depth = 0) msg p =
+	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
 
 
 let adapt_defines_to_macro_context defines =
 let adapt_defines_to_macro_context defines =
-	let to_remove = "java" :: List.map Globals.platform_name Globals.platforms in
+	let to_remove = List.map Globals.platform_name Globals.platforms in
 	let to_remove = List.fold_left (fun acc d -> Define.get_define_key d :: acc) to_remove [Define.NoTraces] in
 	let to_remove = List.fold_left (fun acc d -> Define.get_define_key d :: acc) to_remove [Define.NoTraces] in
 	let to_remove = List.fold_left (fun acc (_, d) -> ("flash" ^ d) :: acc) to_remove flash_versions in
 	let to_remove = List.fold_left (fun acc (_, d) -> ("flash" ^ d) :: acc) to_remove flash_versions in
 	let macro_defines = {
 	let macro_defines = {
@@ -1257,3 +1280,100 @@ let get_entry_point com =
 		let e = Option.get com.main in (* must be present at this point *)
 		let e = Option.get com.main in (* must be present at this point *)
 		(snd path, c, e)
 		(snd path, c, e)
 	) com.main_class
 	) com.main_class
+
+let format_string com s p process_expr =
+	let e = ref None in
+	let pmin = ref p.pmin in
+	let min = ref (p.pmin + 1) in
+	let add_expr (enext,p) len =
+		min := !min + len;
+		let enext = process_expr enext p in
+		match !e with
+		| None -> e := Some enext
+		| Some prev ->
+			e := Some (EBinop (OpAdd,prev,enext),punion (pos prev) p)
+	in
+	let add enext len =
+		let p = { p with pmin = !min; pmax = !min + len } in
+		add_expr (enext,p) len
+	in
+	let add_sub start pos =
+		let len = pos - start in
+		if len > 0 || !e = None then add (EConst (String (String.sub s start len,SDoubleQuotes))) len
+	in
+	let len = String.length s in
+	let rec parse start pos =
+		if pos = len then add_sub start pos else
+		let c = String.unsafe_get s pos in
+		let pos = pos + 1 in
+		if c = '\'' then begin
+			incr pmin;
+			incr min;
+		end;
+		if c <> '$' || pos = len then parse start pos else
+		match String.unsafe_get s pos with
+		| '$' ->
+			(* double $ *)
+			add_sub start pos;
+			parse (pos + 1) (pos + 1)
+		| '{' ->
+			parse_group start pos '{' '}' "brace"
+		| 'a'..'z' | 'A'..'Z' | '_' ->
+			add_sub start (pos - 1);
+			incr min;
+			let rec loop i =
+				if i = len then i else
+				let c = String.unsafe_get s i in
+				match c with
+				| 'a'..'z' | 'A'..'Z' | '0'..'9' | '_' -> loop (i+1)
+				| _ -> i
+			in
+			let iend = loop (pos + 1) in
+			let len = iend - pos in
+			add (EConst (Ident (String.sub s pos len))) len;
+			parse (pos + len) (pos + len)
+		| _ ->
+			(* keep as-it *)
+			parse start pos
+	and parse_group start pos gopen gclose gname =
+		add_sub start (pos - 1);
+		let rec loop groups i =
+			if i = len then
+				match groups with
+				| [] -> die "" __LOC__
+				| g :: _ -> Error.raise_typing_error ("Unclosed " ^ gname) { p with pmin = !pmin + g + 1; pmax = !pmin + g + 2 }
+			else
+				let c = String.unsafe_get s i in
+				if c = gopen then
+					loop (i :: groups) (i + 1)
+				else if c = gclose then begin
+					let groups = List.tl groups in
+					if groups = [] then i else loop groups (i + 1)
+				end else
+					loop groups (i + 1)
+		in
+		let send = loop [pos] (pos + 1) in
+		let slen = send - pos - 1 in
+		let scode = String.sub s (pos + 1) slen in
+		min := !min + 2;
+		begin
+			let e =
+				let ep = { p with pmin = !pmin + pos + 2; pmax = !pmin + send + 1 } in
+				let error msg pos =
+					if Lexer.string_is_whitespace scode then Error.raise_typing_error "Expression cannot be empty" ep
+					else Error.raise_typing_error msg pos
+				in
+				match ParserEntry.parse_expr_string com.defines scode ep error true with
+					| ParseSuccess(data,_,_) -> data
+					| ParseError(_,(msg,p),_) -> error (Parser.error_msg msg) p
+			in
+			add_expr e slen
+		end;
+		min := !min + 1;
+		parse (send + 1) (send + 1)
+	in
+	parse 0 0;
+	match !e with
+	| None -> die "" __LOC__
+	| Some e -> e
+

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

@@ -3,37 +3,46 @@ 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;
+}
+
+let create_context com = {
+	com = com;
+	class_meta = [];
+	field_meta = [];
+}
 
 
 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
+			dctx.com.warning 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 +92,31 @@ 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} 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 cl_meta cf_meta name meta p =
+	let dctx = {
+		com = com;
+		class_meta = cl_meta;
+		field_meta = cf_meta;
+	} 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

+ 33 - 35
src/context/display/diagnostics.ml

@@ -1,12 +1,8 @@
 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 =
 let add_removable_code ctx s p prange =
 	ctx.removable_code <- (s,p,prange) :: ctx.removable_code
 	ctx.removable_code <- (s,p,prange) :: ctx.removable_code
@@ -43,23 +39,23 @@ let find_unused_variables com e =
 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 compiler_generated s el p =
 		let old = !had_effect in
 		let old = !had_effect in
 		had_effect := false;
 		had_effect := false;
-		List.iter (loop true) el;
-		if not !had_effect then no_effect p else pointless_compound s p;
+		List.iter (loop true compiler_generated) el;
+		if not !had_effect then no_effect p else if not compiler_generated then pointless_compound s p;
 		had_effect := old;
 		had_effect := old;
-	and loop in_value e = match e.eexpr with
+	and loop in_value compiler_generated e = match e.eexpr with
 		| TBlock el ->
 		| TBlock el ->
 			let rec loop2 el = match el with
 			let rec loop2 el = match el with
 				| [] -> ()
 				| [] -> ()
-				| [e] -> loop in_value e
-				| e :: el -> loop false e; loop2 el
+				| [e] -> loop in_value compiler_generated e
+				| e :: el -> loop false compiler_generated e; loop2 el
 			in
 			in
 			loop2 el
 			loop2 el
 		| TMeta((Meta.Extern,_,_),_) ->
 		| TMeta((Meta.Extern,_,_),_) ->
@@ -71,42 +67,46 @@ let check_other_things com e =
 			()
 			()
 		| TField (_, fa) when PurityState.is_explicitly_impure fa -> ()
 		| TField (_, fa) when PurityState.is_explicitly_impure fa -> ()
 		| TFunction tf ->
 		| TFunction tf ->
-			loop false tf.tf_expr
-		| TCall({eexpr = TField(e1,fa)},el) when not in_value && PurityState.is_pure_field_access fa -> compound "call" el e.epos
+			loop false compiler_generated tf.tf_expr
+		| TCall({eexpr = TField(e1,fa)},el) when not in_value && PurityState.is_pure_field_access fa -> compound compiler_generated "call" el e.epos
 		| TNew _ | TCall _ | TBinop ((Ast.OpAssignOp _ | Ast.OpAssign),_,_) | TUnop ((Ast.Increment | Ast.Decrement),_,_)
 		| TNew _ | TCall _ | TBinop ((Ast.OpAssignOp _ | Ast.OpAssign),_,_) | TUnop ((Ast.Increment | Ast.Decrement),_,_)
 		| TReturn _ | TBreak | TContinue | TThrow _ | TCast (_,Some _)
 		| TReturn _ | TBreak | TContinue | TThrow _ | TCast (_,Some _)
 		| TIf _ | TTry _ | TSwitch _ | TWhile _ | TFor _ ->
 		| TIf _ | TTry _ | TSwitch _ | TWhile _ | TFor _ ->
 			had_effect := true;
 			had_effect := true;
-			Type.iter (loop true) e
+			Type.iter (loop true compiler_generated) e
+		| TMeta((Meta.CompilerGenerated,_,_),e1) ->
+			loop in_value true e1
 		| TParenthesis e1 | TMeta(_,e1) ->
 		| TParenthesis e1 | TMeta(_,e1) ->
-			loop in_value e1
+			loop in_value compiler_generated e1
 		| TArray _ | TCast (_,None) | TBinop _ | TUnop _
 		| TArray _ | TCast (_,None) | TBinop _ | TUnop _
 		| TField _ | TArrayDecl _ | TObjectDecl _ when in_value ->
 		| TField _ | TArrayDecl _ | TObjectDecl _ when in_value ->
-			Type.iter (loop true) e;
-		| TArray(e1,e2) -> compound "array access" [e1;e2] e.epos
-		| TCast(e1,None) -> compound "cast" [e1] e.epos
-		| TBinop(op,e1,e2) -> compound (Printf.sprintf "'%s' operator" (s_binop op)) [e1;e2] e.epos
-		| TUnop(op,_,e1) -> compound (Printf.sprintf "'%s' operator" (s_unop op)) [e1] e.epos
-		| TField(e1,_) -> compound "field access" [e1] e.epos
-		| TArrayDecl el -> compound "array declaration" el e.epos
-		| TObjectDecl fl -> compound "object declaration" (List.map snd fl) e.epos
+			Type.iter (loop true compiler_generated) e;
+		| TArray(e1,e2) -> compound compiler_generated "array access" [e1;e2] e.epos
+		| TCast(e1,None) -> compound compiler_generated "cast" [e1] e.epos
+		| TBinop(op,e1,e2) -> compound compiler_generated (Printf.sprintf "'%s' operator" (s_binop op)) [e1;e2] e.epos
+		| TUnop(op,_,e1) -> compound compiler_generated (Printf.sprintf "'%s' operator" (s_unop op)) [e1] e.epos
+		| TField(e1,_) -> compound compiler_generated "field access" [e1] e.epos
+		| TArrayDecl el -> compound compiler_generated "array declaration" el e.epos
+		| TObjectDecl fl -> compound compiler_generated "object declaration" (List.map snd fl) e.epos
 	in
 	in
-	loop true e
+	loop true false 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;
@@ -143,7 +143,7 @@ let prepare com =
 		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 ->
@@ -178,9 +178,7 @@ let prepare com =
 	dctx
 	dctx
 
 
 let secure_generated_code ctx e =
 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
+	if is_diagnostics ctx then mk (TMeta((Meta.CompilerGenerated,[],e.epos),e)) e.etype e.epos else e
 
 
 let print com =
 let print com =
 	let dctx = prepare com in
 	let dctx = prepare com in
@@ -188,4 +186,4 @@ let print com =
 
 
 let run com =
 let run com =
 	let dctx = prepare com in
 	let dctx = prepare com in
-	dctx
+	dctx

+ 20 - 17
src/context/display/diagnosticsPrinter.ml

@@ -2,7 +2,6 @@ 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
@@ -11,14 +10,16 @@ type t = {
 	diag_kind : MessageKind.t;
 	diag_kind : MessageKind.t;
 	diag_pos : pos;
 	diag_pos : pos;
 	diag_severity : MessageSeverity.t;
 	diag_severity : MessageSeverity.t;
+	diag_code : string option;
 	diag_args : Json.t;
 	diag_args : Json.t;
 	mutable diag_related_information : (pos * int * string) list;
 	mutable diag_related_information : (pos * int * string) list;
 }
 }
 
 
-let make_diagnostic kd p sev args = {
+let make_diagnostic kd p sev code args = {
 	diag_kind = kd;
 	diag_kind = kd;
 	diag_pos = p;
 	diag_pos = p;
 	diag_severity = sev;
 	diag_severity = sev;
+	diag_code = code;
 	diag_args = args;
 	diag_args = args;
 	diag_related_information = [];
 	diag_related_information = [];
 }
 }
@@ -60,7 +61,7 @@ let json_of_diagnostics com dctx =
 			Hashtbl.replace diagnostics file (diag :: fdiag)
 			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
 			| DKRemovableCode
@@ -74,7 +75,7 @@ let json_of_diagnostics com dctx =
 				true
 				true
 		in
 		in
 		if p = null_pos || is_diagnostics_file com (file_keys#get p.pfile) then begin
 		if p = null_pos || is_diagnostics_file com (file_keys#get p.pfile) then begin
-			let diag = make_diagnostic dk p sev args in
+			let diag = make_diagnostic dk p sev code args in
 			current := Some diag;
 			current := Some diag;
 			add append diag
 			add append diag
 		end else current := None
 		end else current := None
@@ -97,19 +98,19 @@ 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,depth) -> match (depth, !current) with
-		| d, Some diag when d > 0 ->
-			let lines = ExtString.String.nsplit s "\n" in
+	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
 			(match lines with
 				| [] -> ()
 				| [] -> ()
 				| s :: sub ->
 				| s :: sub ->
-					let related = List.fold_left (fun acc s -> (p,d,Error.compl_msg s) :: acc) diag.diag_related_information sub in
-					diag.diag_related_information <- (p,d,s) :: related;
+					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, _ ->
 		| 0, _ ->
-			add kind p sev (JString s)
+			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. *)
 			(* 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 *)
 			(* This could happen when running diagnostics for a file that is wentioned in *)
@@ -177,22 +178,23 @@ 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) ->
 	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])
+		add DKRemovableCode p MessageSeverity.Warning None (JObject ["description",JString s;"range",if prange = null_pos then JNull else Genjson.generate_pos_as_range prange])
 	) dctx.removable_code;
 	) dctx.removable_code;
 	Hashtbl.iter (fun file ranges ->
 	Hashtbl.iter (fun file ranges ->
 		List.iter (fun (p,e) ->
 		List.iter (fun (p,e) ->
@@ -201,7 +203,7 @@ 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 ->
@@ -211,8 +213,9 @@ let json_of_diagnostics com dctx =
 				"severity",JInt (MessageSeverity.to_int diag.diag_severity);
 				"severity",JInt (MessageSeverity.to_int diag.diag_severity);
 				"range",Genjson.generate_pos_as_range diag.diag_pos;
 				"range",Genjson.generate_pos_as_range diag.diag_pos;
 				"args",diag.diag_args;
 				"args",diag.diag_args;
+				"code",(match diag.diag_code with None -> JNull | Some c -> JString c);
 				"relatedInformation",JArray (
 				"relatedInformation",JArray (
-					List.rev_map (fun (pos,depth,msg) -> (JObject [
+					List.map (fun (pos,depth,msg) -> (JObject [
 						"location",Genjson.generate_pos_as_location pos;
 						"location",Genjson.generate_pos_as_location pos;
 						"depth",JInt depth;
 						"depth",JInt depth;
 						"message",JString msg;
 						"message",JString msg;

+ 1 - 4
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
 
 
@@ -290,7 +287,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

+ 12 - 2
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
@@ -192,4 +202,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

+ 24 - 20
src/context/display/displayFields.ml

@@ -75,7 +75,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
 		| _ ->
 		| _ ->
@@ -228,21 +228,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 +261,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 +271,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 +377,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 +413,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

+ 9 - 3
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
@@ -183,13 +182,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
@@ -297,6 +297,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 ->

+ 3 - 6
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,12 +57,11 @@ 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";
 	ignore(follow cf.cf_type)
 	ignore(follow cf.cf_type)
@@ -184,4 +181,4 @@ let check_display_file ctx cs =
 			cs#taint_modules fkey "check_display_file";
 			cs#taint_modules fkey "check_display_file";
 		end
 		end
 	| None ->
 	| None ->
-		()
+		()

+ 4 - 5
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");
@@ -460,7 +459,7 @@ let collect ctx tk with_type sort =
 	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

+ 1 - 1
src/context/display/documentSymbols.ml

@@ -56,7 +56,7 @@ let collect_module_symbols mname with_locals (pack,decls) =
 		| FFun f ->
 		| FFun f ->
 			add_field (
 			add_field (
 				if fst cff_name = "new" then Constructor
 				if fst cff_name = "new" then Constructor
-				else if ((parent_kind = EnumAbstract or parent_kind = Abstract) && Meta.has_one_of [Meta.Op; Meta.ArrayAccess; Meta.Resolve] cff_meta) then Operator
+				else if ((parent_kind = EnumAbstract || parent_kind = Abstract) && Meta.has_one_of [Meta.Op; Meta.ArrayAccess; Meta.Resolve] cff_meta) then Operator
 				else Method
 				else Method
 			);
 			);
 			if with_locals then func field_parent f
 			if with_locals then func field_parent f

+ 1 - 3
src/context/display/findReferences.ml

@@ -1,10 +1,8 @@
 open Globals
 open Globals
-open Ast
 open DisplayTypes
 open DisplayTypes
 open Common
 open Common
 open Type
 open Type
 open Typecore
 open Typecore
-open ImportHandling
 
 
 let find_possible_references tctx cs =
 let find_possible_references tctx cs =
 	let name,_,kind = Display.ReferencePosition.get () in
 	let name,_,kind = Display.ReferencePosition.get () in
@@ -164,4 +162,4 @@ let find_implementations tctx com name pos kind =
 let find_implementations tctx com =
 let find_implementations tctx com =
 	let name,pos,kind = Display.ReferencePosition.get () in
 	let name,pos,kind = Display.ReferencePosition.get () in
 	if pos <> null_pos then find_implementations tctx com name pos kind
 	if pos <> null_pos then find_implementations tctx com name pos kind
-	else DisplayException.raise_positions []
+	else DisplayException.raise_positions []

+ 64 - 58
src/context/display/importHandling.ml

@@ -5,6 +5,7 @@ open Common
 open Type
 open Type
 open Error
 open Error
 open Typecore
 open Typecore
+open Resolution
 
 
 type import_display_kind =
 type import_display_kind =
 	| IDKPackage of string list
 	| IDKPackage of string list
@@ -61,7 +62,7 @@ let commit_import ctx path mode p =
 	ctx.m.import_statements <- (path,mode) :: ctx.m.import_statements;
 	ctx.m.import_statements <- (path,mode) :: ctx.m.import_statements;
 	if Filename.basename p.pfile <> "import.hx" then add_import_position ctx p path
 	if Filename.basename p.pfile <> "import.hx" then add_import_position ctx p path
 
 
-let init_import ctx context_init path mode p =
+let init_import ctx path mode p =
 	let rec loop acc = function
 	let rec loop acc = function
 		| x :: l when is_lower_ident (fst x) -> loop (x::acc) l
 		| x :: l when is_lower_ident (fst x) -> loop (x::acc) l
 		| rest -> List.rev acc, rest
 		| rest -> List.rev acc, rest
@@ -71,19 +72,19 @@ let init_import ctx context_init path mode p =
 	| [] ->
 	| [] ->
 		(match mode with
 		(match mode with
 		| IAll ->
 		| IAll ->
-			ctx.m.wildcard_packages <- (List.map fst pack,p) :: ctx.m.wildcard_packages
+			ctx.m.import_resolution#add (wildcard_package_resolution (List.map fst pack) p)
 		| _ ->
 		| _ ->
 			(match List.rev path with
 			(match List.rev path with
 			(* p spans `import |` (to the display position), so we take the pmax here *)
 			(* p spans `import |` (to the display position), so we take the pmax here *)
 			| [] -> DisplayException.raise_fields (DisplayToplevel.collect ctx TKType NoValue true) CRImport (DisplayTypes.make_subject None {p with pmin = p.pmax})
 			| [] -> DisplayException.raise_fields (DisplayToplevel.collect ctx TKType NoValue true) CRImport (DisplayTypes.make_subject None {p with pmin = p.pmax})
-			| (_,p) :: _ -> Error.typing_error "Module name must start with an uppercase letter" p))
+			| (_,p) :: _ -> Error.raise_typing_error "Module name must start with an uppercase letter" p))
 	| (tname,p2) :: rest ->
 	| (tname,p2) :: rest ->
 		let p1 = (match pack with [] -> p2 | (_,p1) :: _ -> p1) in
 		let p1 = (match pack with [] -> p2 | (_,p1) :: _ -> p1) in
 		let p_type = punion p1 p2 in
 		let p_type = punion p1 p2 in
 		let md = ctx.g.do_load_module ctx (List.map fst pack,tname) p_type in
 		let md = ctx.g.do_load_module ctx (List.map fst pack,tname) p_type in
 		let types = md.m_types in
 		let types = md.m_types in
-		let no_private (t,_) = not (t_infos t).mt_private in
-		let error_private p = typing_error "Importing private declarations from a module is not allowed" p in
+		let not_private mt = not (t_infos mt).mt_private in
+		let error_private p = raise_typing_error "Importing private declarations from a module is not allowed" p in
 		let chk_private t p = if ctx.m.curmod != (t_infos t).mt_module && (t_infos t).mt_private then error_private p in
 		let chk_private t p = if ctx.m.curmod != (t_infos t).mt_module && (t_infos t).mt_private then error_private p in
 		let has_name name t = snd (t_infos t).mt_path = name in
 		let has_name name t = snd (t_infos t).mt_path = name in
 
 
@@ -93,7 +94,7 @@ let init_import ctx context_init path mode p =
 				| 'a'..'z' -> "field", PMap.foldi (fun n _ acc -> n :: acc) (try (Option.get md.m_statics).cl_statics with | _ -> PMap.empty) []
 				| 'a'..'z' -> "field", PMap.foldi (fun n _ acc -> n :: acc) (try (Option.get md.m_statics).cl_statics with | _ -> PMap.empty) []
 				| _ -> "type", List.map (fun mt -> snd (t_infos mt).mt_path) types
 				| _ -> "type", List.map (fun mt -> snd (t_infos mt).mt_path) types
 			in
 			in
-			typing_error (StringError.string_error name
+			raise_typing_error (StringError.string_error name
 				candidates
 				candidates
 				("Module " ^ s_type_path md.m_path ^ " does not define " ^ target_kind ^ " " ^ name)
 				("Module " ^ s_type_path md.m_path ^ " does not define " ^ target_kind ^ " " ^ name)
 			) p
 			) p
@@ -109,66 +110,70 @@ let init_import ctx context_init path mode p =
 			chk_private t p_type;
 			chk_private t p_type;
 			t
 			t
 		in
 		in
-		let rebind t name p =
+		let check_alias mt name pname =
 			if not (name.[0] >= 'A' && name.[0] <= 'Z') then
 			if not (name.[0] >= 'A' && name.[0] <= 'Z') then
-				typing_error "Type aliases must start with an uppercase letter" p;
-			let _, _, f = ctx.g.do_build_instance ctx t p_type in
-			(* create a temp private typedef, does not register it in module *)
-			let t_path = (fst md.m_path @ ["_" ^ snd md.m_path],name) in
-			let t_type = f (extract_param_types (t_infos t).mt_params) in
-			let mt = TTypeDecl {(mk_typedef ctx.m.curmod t_path p p t_type) with
-				t_private = true;
-				t_params = (t_infos t).mt_params
-			} in
-			if ctx.is_display_file && DisplayPosition.display_position#enclosed_in p then
-				DisplayEmitter.display_module_type ctx mt p;
-			mt
+				raise_typing_error "Type aliases must start with an uppercase letter" pname;
+			if ctx.is_display_file && DisplayPosition.display_position#enclosed_in pname then
+				DisplayEmitter.display_alias ctx name (type_of_module_type mt) pname;
 		in
 		in
 		let add_static_init t name s =
 		let add_static_init t name s =
-			let name = (match name with None -> s | Some (n,_) -> n) in
 			match resolve_typedef t with
 			match resolve_typedef t with
-			| TClassDecl c | TAbstractDecl {a_impl = Some c} ->
+			| TClassDecl c ->
 				ignore(c.cl_build());
 				ignore(c.cl_build());
-				ignore(PMap.find s c.cl_statics);
-				ctx.m.module_globals <- PMap.add name (TClassDecl c,s,p) ctx.m.module_globals
-			| TEnumDecl e ->
-				ignore(PMap.find s e.e_constrs);
-				ctx.m.module_globals <- PMap.add name (TEnumDecl e,s,p) ctx.m.module_globals
+				let cf = PMap.find s c.cl_statics in
+				static_field_resolution c cf name p
+			| TAbstractDecl ({a_impl = Some c} as a) ->
+				ignore(c.cl_build());
+				let cf = PMap.find s c.cl_statics in
+				static_abstract_field_resolution a c cf name p
+			| TEnumDecl en ->
+				let ef = PMap.find s en.e_constrs in
+				enum_constructor_resolution en ef name p
 			| _ ->
 			| _ ->
 				raise Not_found
 				raise Not_found
 		in
 		in
+		let add_lazy_resolution f =
+			ctx.m.import_resolution#add (lazy_resolution f)
+		in
 		(match mode with
 		(match mode with
 		| INormal | IAsName _ ->
 		| INormal | IAsName _ ->
 			let name = (match mode with IAsName n -> Some n | _ -> None) in
 			let name = (match mode with IAsName n -> Some n | _ -> None) in
 			(match rest with
 			(match rest with
 			| [] ->
 			| [] ->
-				(match name with
+				begin match name with
 				| None ->
 				| None ->
-					ctx.m.module_imports <- List.filter no_private (List.map (fun t -> t,p) types) @ ctx.m.module_imports;
+					List.iter (fun mt ->
+						if not_private mt then
+							ctx.m.import_resolution#add (module_type_resolution mt None p)
+					) (List.rev types);
 					Option.may (fun c ->
 					Option.may (fun c ->
-						context_init#add (fun () ->
-							ignore(c.cl_build());
-							List.iter (fun cf ->
-								if has_class_field_flag cf CfPublic then
-									ctx.m.module_globals <- PMap.add cf.cf_name (TClassDecl c,cf.cf_name,p) ctx.m.module_globals
-							) c.cl_ordered_statics
-						);
+						ctx.m.import_resolution#add (class_statics_resolution c p)
 					) md.m_statics
 					) md.m_statics
 				| Some(newname,pname) ->
 				| Some(newname,pname) ->
-					ctx.m.module_imports <- (rebind (get_type tname) newname pname,p) :: ctx.m.module_imports);
+					let mt = get_type tname in
+					check_alias mt newname pname;
+					ctx.m.import_resolution#add (module_type_resolution mt (Some newname) p2)
+				end
 			| [tsub,p2] ->
 			| [tsub,p2] ->
 				let pu = punion p1 p2 in
 				let pu = punion p1 p2 in
 				(try
 				(try
 					let tsub = List.find (has_name tsub) types in
 					let tsub = List.find (has_name tsub) types in
 					chk_private tsub pu;
 					chk_private tsub pu;
-					ctx.m.module_imports <- ((match name with None -> tsub | Some(n,pname) -> rebind tsub n pname),p) :: ctx.m.module_imports
+					let alias = match name with
+						| None ->
+							None
+						| Some(name,pname) ->
+							check_alias tsub name pname;
+							Some name
+					in
+					ctx.m.import_resolution#add (module_type_resolution tsub alias p2);
 				with Not_found ->
 				with Not_found ->
 					(* this might be a static property, wait later to check *)
 					(* this might be a static property, wait later to check *)
 					let find_main_type_static () =
 					let find_main_type_static () =
 						try
 						try
 							let tmain = find_type tname in
 							let tmain = find_type tname in
 							begin try
 							begin try
-								add_static_init tmain name tsub
+								Some (add_static_init tmain (Option.map fst name) tsub)
 							with Not_found ->
 							with Not_found ->
 								let parent,target_kind,candidates = match resolve_typedef tmain with
 								let parent,target_kind,candidates = match resolve_typedef tmain with
 									| TClassDecl c ->
 									| TClassDecl c ->
@@ -189,13 +194,13 @@ let init_import ctx context_init path mode p =
 										(* TODO: cleaner way to get module fields? *)
 										(* TODO: cleaner way to get module fields? *)
 										PMap.foldi (fun n _ acc -> n :: acc) (try (Option.get md.m_statics).cl_statics with | _ -> PMap.empty) []
 										PMap.foldi (fun n _ acc -> n :: acc) (try (Option.get md.m_statics).cl_statics with | _ -> PMap.empty) []
 								in
 								in
-
-								display_error ctx.com (StringError.string_error tsub candidates (parent ^ " has no " ^ target_kind ^ " " ^ tsub)) p
+								display_error ctx.com (StringError.string_error tsub candidates (parent ^ " has no " ^ target_kind ^ " " ^ tsub)) p;
+								None
 							end
 							end
 						with Not_found ->
 						with Not_found ->
 							fail_usefully tsub p
 							fail_usefully tsub p
 					in
 					in
-					context_init#add (fun() ->
+					add_lazy_resolution (fun() ->
 						match md.m_statics with
 						match md.m_statics with
 						| Some c ->
 						| Some c ->
 							(try
 							(try
@@ -208,8 +213,7 @@ let init_import ctx context_init path mode p =
 											if not (has_class_field_flag cf CfPublic) then
 											if not (has_class_field_flag cf CfPublic) then
 												error_private p
 												error_private p
 											else
 											else
-												let imported_name = match name with None -> tsub | Some (n,pname) -> n in
-												ctx.m.module_globals <- PMap.add imported_name (TClassDecl c,tsub,p) ctx.m.module_globals;
+												Some (static_field_resolution c cf (Option.map fst name) p)
 										else
 										else
 											loop rest
 											loop rest
 								in
 								in
@@ -223,31 +227,31 @@ let init_import ctx context_init path mode p =
 			| (tsub,p2) :: (fname,p3) :: rest ->
 			| (tsub,p2) :: (fname,p3) :: rest ->
 				(match rest with
 				(match rest with
 				| [] -> ()
 				| [] -> ()
-				| (n,p) :: _ -> typing_error ("Unexpected " ^ n) p);
+				| (n,p) :: _ -> raise_typing_error ("Unexpected " ^ n) p);
 				let tsub = get_type tsub in
 				let tsub = get_type tsub in
-				context_init#add (fun() ->
+				add_lazy_resolution (fun() ->
 					try
 					try
-						add_static_init tsub name fname
+						Some (add_static_init tsub (Option.map fst name) fname)
 					with Not_found ->
 					with Not_found ->
-						display_error ctx.com (s_type_path (t_infos tsub).mt_path ^ " has no field " ^ fname) (punion p p3)
+						display_error ctx.com (s_type_path (t_infos tsub).mt_path ^ " has no field " ^ fname) (punion p p3);
+						None
 				);
 				);
 			)
 			)
 		| IAll ->
 		| IAll ->
 			let t = (match rest with
 			let t = (match rest with
 				| [] -> get_type tname
 				| [] -> get_type tname
 				| [tsub,_] -> get_type tsub
 				| [tsub,_] -> get_type tsub
-				| _ :: (n,p) :: _ -> typing_error ("Unexpected " ^ n) p
+				| _ :: (n,p) :: _ -> raise_typing_error ("Unexpected " ^ n) p
 			) in
 			) in
-			context_init#add (fun() ->
+			add_lazy_resolution (fun() ->
 				match resolve_typedef t with
 				match resolve_typedef t with
 				| TClassDecl c
 				| TClassDecl c
 				| TAbstractDecl {a_impl = Some c} ->
 				| TAbstractDecl {a_impl = Some c} ->
-					ignore(c.cl_build());
-					PMap.iter (fun _ cf -> if not (has_meta Meta.NoImportGlobal cf.cf_meta) then ctx.m.module_globals <- PMap.add cf.cf_name (TClassDecl c,cf.cf_name,p) ctx.m.module_globals) c.cl_statics
-				| TEnumDecl e ->
-					PMap.iter (fun _ c -> if not (has_meta Meta.NoImportGlobal c.ef_meta) then ctx.m.module_globals <- PMap.add c.ef_name (TEnumDecl e,c.ef_name,p) ctx.m.module_globals) e.e_constrs
+					Some (class_statics_resolution c p)
+				| TEnumDecl en ->
+					Some (enum_statics_resolution en p)
 				| _ ->
 				| _ ->
-					typing_error "No statics to import from this type" p
+					raise_typing_error "No statics to import from this type" p
 			)
 			)
 		))
 		))
 
 
@@ -270,7 +274,6 @@ let handle_using ctx path p =
 			let t = ctx.g.do_load_type_def ctx p t in
 			let t = ctx.g.do_load_type_def ctx p t in
 			[t]
 			[t]
 	) in
 	) in
-	(* delay the using since we need to resolve typedefs *)
 	let filter_classes types =
 	let filter_classes types =
 		let rec loop acc types = match types with
 		let rec loop acc types = match types with
 			| td :: l ->
 			| td :: l ->
@@ -286,8 +289,11 @@ let handle_using ctx path p =
 	in
 	in
 	types,filter_classes
 	types,filter_classes
 
 
-let init_using ctx context_init path p =
+let init_using ctx path p =
 	let types,filter_classes = handle_using ctx path p in
 	let types,filter_classes = handle_using ctx path p in
 	(* do the import first *)
 	(* do the import first *)
-	ctx.m.module_imports <- (List.map (fun t -> t,p) types) @ ctx.m.module_imports;
-	context_init#add (fun() -> ctx.m.module_using <- filter_classes types @ ctx.m.module_using)
+	List.iter (fun mt ->
+		ctx.m.import_resolution#add (module_type_resolution mt None p)
+	) (List.rev types);
+	(* delay the using since we need to resolve typedefs *)
+	delay_late ctx PConnectField (fun () -> ctx.m.module_using <- filter_classes types @ ctx.m.module_using)

+ 1 - 4
src/context/display/statistics.ml

@@ -1,12 +1,9 @@
 open Globals
 open Globals
-open Ast
 open Type
 open Type
 open Common
 open Common
 open Typecore
 open Typecore
 open DisplayTypes
 open DisplayTypes
 
 
-open ImportHandling
-
 type relation =
 type relation =
 	| Implemented
 	| Implemented
 	| Extended
 	| Extended
@@ -367,4 +364,4 @@ module Printer = struct
 			]) :: acc
 			]) :: acc
 		) files [] in
 		) files [] in
 		string_of_json (JArray ja)
 		string_of_json (JArray ja)
-end
+end

+ 9 - 7
src/context/memory.ml

@@ -1,5 +1,4 @@
 open Globals
 open Globals
-open CompilationCache
 open Common
 open Common
 open Type
 open Type
 open Genjson
 open Genjson
@@ -34,12 +33,14 @@ let update_module_type_deps deps md =
 	) md.m_types;
 	) md.m_types;
 	!deps
 	!deps
 
 
-let rec scan_module_deps m h =
+let rec scan_module_deps cs m h =
 	if Hashtbl.mem h m.m_id then
 	if Hashtbl.mem h m.m_id then
 		()
 		()
 	else begin
 	else begin
 		Hashtbl.add h m.m_id m;
 		Hashtbl.add h m.m_id m;
-		PMap.iter (fun _ m -> scan_module_deps m h) m.m_extra.m_deps
+		PMap.iter (fun _ (sign,mpath) ->
+			let m = (cs#get_context sign)#find_module mpath in
+			scan_module_deps cs m h) m.m_extra.m_deps
 	end
 	end
 
 
 let module_sign key md =
 let module_sign key md =
@@ -62,7 +63,7 @@ let get_out out =
 
 
 let get_module_memory cs all_modules m =
 let get_module_memory cs all_modules m =
 	let mdeps = Hashtbl.create 0 in
 	let mdeps = Hashtbl.create 0 in
-	scan_module_deps m mdeps;
+	scan_module_deps cs m mdeps;
 	let deps = ref [Obj.repr null_module] in
 	let deps = ref [Obj.repr null_module] in
 	let out = ref all_modules in
 	let out = ref all_modules in
 	let deps = Hashtbl.fold (fun _ md deps ->
 	let deps = Hashtbl.fold (fun _ md deps ->
@@ -273,8 +274,9 @@ let display_memory com =
 			());
 			());
 		if verbose then begin
 		if verbose then begin
 			print (Printf.sprintf "      %d total deps" (List.length deps));
 			print (Printf.sprintf "      %d total deps" (List.length deps));
-			PMap.iter (fun _ md ->
-				print (Printf.sprintf "      dep %s%s" (s_type_path md.m_path) (module_sign key md));
+			PMap.iter (fun _ (sign,mpath) ->
+				let md = (com.cs#get_context sign)#find_module mpath in
+				print (Printf.sprintf "      dep %s%s" (s_type_path mpath) (module_sign key md));
 			) m.m_extra.m_deps;
 			) m.m_extra.m_deps;
 		end;
 		end;
 		flush stdout
 		flush stdout
@@ -283,4 +285,4 @@ let display_memory com =
 		if k1 = k2 then s1 - s2 else if k1 > k2 then 1 else -1
 		if k1 = k2 then s1 - s2 else if k1 > k2 then 1 else -1
 	) modules);
 	) modules);
 	if !mcount > 0 then print ("*** " ^ string_of_int !mcount ^ " modules have leaks !");
 	if !mcount > 0 then print ("*** " ^ string_of_int !mcount ^ " modules have leaks !");
-	print "Cache dump complete"
+	print "Cache dump complete"

+ 1 - 2
src/context/nativeLibraries.ml

@@ -18,7 +18,6 @@
  *)
  *)
 
 
 open Globals
 open Globals
-open ExtString
 
 
 type native_lib_flags =
 type native_lib_flags =
 	| FlagIsStd
 	| FlagIsStd
@@ -54,4 +53,4 @@ let create_native_libs () = {
 	java_libs = [];
 	java_libs = [];
 	swf_libs = [];
 	swf_libs = [];
 	all_libs = [];
 	all_libs = [];
-}
+}

+ 2 - 2
src/context/purityState.ml

@@ -29,12 +29,12 @@ let get_purity_from_meta meta =
 			| "true" | "inferredPure" -> Pure
 			| "true" | "inferredPure" -> Pure
 			| "false" -> Impure
 			| "false" -> Impure
 			| "expect" -> ExpectPure p
 			| "expect" -> ExpectPure p
-			| _ -> typing_error ("Unsupported purity value " ^ s ^ ", expected true or false") p
+			| _ -> raise_typing_error ("Unsupported purity value " ^ s ^ ", expected true or false") p
 			end
 			end
 		| (_,[],_) ->
 		| (_,[],_) ->
 			Pure
 			Pure
 		| (_,_,p) ->
 		| (_,_,p) ->
-			typing_error "Unsupported purity value" p
+			raise_typing_error "Unsupported purity value" p
 		end
 		end
 	with Not_found ->
 	with Not_found ->
 		MaybePure
 		MaybePure

+ 248 - 0
src/context/resolution.ml

@@ -0,0 +1,248 @@
+open Globals
+open Type
+
+type resolution_kind =
+	| RTypeImport of string* module_type
+	| RClassFieldImport of string * tclass * tclass_field
+	| RAbstractFieldImport of string * tabstract * tclass * tclass_field
+	| REnumConstructorImport of string * tenum * tenum_field
+	| RWildcardPackage of string list
+	| RClassStatics of tclass
+	| REnumStatics of tenum
+	| RLazy of (unit -> resolution option)
+
+and resolution = {
+	r_kind : resolution_kind;
+	r_pos : pos;
+}
+
+let mk_resolution kind p = {
+	r_kind = kind;
+	r_pos = p;
+}
+
+let lazy_resolution f =
+	mk_resolution (RLazy f) null_pos
+
+let module_type_resolution mt alias p =
+	mk_resolution (RTypeImport((Option.default (t_name mt) alias),mt)) p
+
+let static_field_resolution c cf alias p =
+	mk_resolution (RClassFieldImport((Option.default cf.cf_name alias),c,cf)) p
+
+let static_abstract_field_resolution a c cf alias p =
+	mk_resolution (RAbstractFieldImport((Option.default cf.cf_name alias),a,c,cf)) p
+
+let enum_constructor_resolution en ef alias p =
+	mk_resolution (REnumConstructorImport((Option.default ef.ef_name alias),en,ef)) p
+
+let class_statics_resolution c p =
+	mk_resolution (RClassStatics c) p
+
+let enum_statics_resolution en p =
+	mk_resolution (REnumStatics en) p
+
+let wildcard_package_resolution sl p =
+	mk_resolution (RWildcardPackage sl) p
+
+let as_importable_static c cf p =
+	if not (has_meta Meta.NoImportGlobal cf.cf_meta) then begin match c.cl_kind with
+		| KAbstractImpl a ->
+			if a.a_enum && not (has_class_field_flag cf CfEnum) then
+				None
+			else
+				Some (cf.cf_name,static_abstract_field_resolution a c cf None p)
+		| _ ->
+			Some (cf.cf_name,static_field_resolution c cf None p)
+	end else
+		None
+
+let s_resolution_kind = function
+	| RTypeImport(_,mt) -> Printf.sprintf "RTypeImport(%s)" (s_type_path (t_infos mt).mt_path)
+	| RClassFieldImport(_,c,cf) -> Printf.sprintf "RClassFieldImport(%s, %s)" (s_type_path c.cl_path) cf.cf_name
+	| RAbstractFieldImport(_,a,c,cf) -> Printf.sprintf "RAbstractFieldImport(%s, %s)" (s_type_path a.a_path) cf.cf_name
+	| REnumConstructorImport(_,en,ef) -> Printf.sprintf "REnumConstructorImport(%s, %s)" (s_type_path en.e_path) ef.ef_name
+	| RWildcardPackage sl -> Printf.sprintf "RWildcardPackage(%s)" (String.concat "." sl)
+	| RClassStatics c -> Printf.sprintf "RClassStatics(%s)" (s_type_path c.cl_path)
+	| REnumStatics en -> Printf.sprintf "REnumStatics(%s)" (s_type_path en.e_path)
+	| RLazy _ -> "RLazy"
+
+class resolution_list (id : string list) = object(self)
+	val mutable l = []
+	val mutable resolved_lazies = true
+	val mutable cached_type_imports = true
+	val mutable type_import_cache = StringMap.empty
+
+	method add (res : resolution) =
+		l <- res :: l;
+		(* If we import a type, we automatically want to import all its constructors in case of
+		   enums and enum abstracts. We add a RLazy in front of the list so that it takes priority
+		   over the type itself. When resolved, it will insert its fields into the resolution list. *)
+		begin match res.r_kind with
+		| RTypeImport(_,mt) ->
+			Option.may (fun res -> l <- res :: l) (self#expand_enum_constructors mt);
+			cached_type_imports <- false;
+		| RLazy _ ->
+			resolved_lazies <- false;
+		| _ ->
+			()
+		end
+
+	method resolve_lazies =
+		let rec loop acc l = match l with
+			| {r_kind = RLazy f} :: l ->
+				begin match f() with
+				| None ->
+					loop acc l
+				| Some res ->
+					loop acc (res :: l)
+				end
+			| res :: l ->
+				loop (res :: acc) l
+			| [] ->
+				List.rev acc
+		in
+		if not resolved_lazies then begin
+			resolved_lazies <- true;
+			l <- loop [] l;
+		end
+
+	method resolve (i : string) : resolution =
+		self#resolve_lazies;
+		let rec loop l = match l with
+			| [] ->
+				raise Not_found
+			| res :: l ->
+				begin match res.r_kind with
+				| RClassStatics c ->
+					ignore(c.cl_build());
+					begin try
+						let cf = PMap.find i c.cl_statics in
+						begin match as_importable_static c cf res.r_pos with
+						| None ->
+							loop l
+						| Some(_,res) ->
+							res
+						end;
+					with Not_found ->
+						loop l
+					end
+				| REnumStatics en ->
+					begin try
+						let ef = PMap.find i en.e_constrs in
+						if not (has_meta Meta.NoImportGlobal ef.ef_meta) then
+							enum_constructor_resolution en ef None res.r_pos
+						else
+							loop l
+					with Not_found ->
+						loop l
+					end
+				| RTypeImport(alias,_) | RClassFieldImport(alias,_,_) | RAbstractFieldImport(alias,_,_,_) | REnumConstructorImport(alias,_,_) ->
+					if alias = i then
+						res
+					else
+						loop l
+				| RLazy _ | RWildcardPackage _ ->
+					loop l
+				end
+		in
+		loop l
+
+	method expand_enum_constructors (mt : module_type) = match mt with
+		| TAbstractDecl ({a_impl = Some c} as a) when a.a_enum ->
+			Some (class_statics_resolution c null_pos)
+		| TEnumDecl en ->
+			Some (enum_statics_resolution en null_pos)
+		| TTypeDecl t ->
+			let f () =
+				begin match follow t.t_type with
+					| TEnum (e,_) -> self#expand_enum_constructors (TEnumDecl e)
+					| TAbstract (a,_) when a.a_enum -> self#expand_enum_constructors (TAbstractDecl a)
+					| _ -> None
+				end
+			in
+			resolved_lazies <- false;
+			Some (lazy_resolution f)
+		| TClassDecl _ | TAbstractDecl _ ->
+			None
+
+	method save =
+		let l' = l in
+		let resolved_lazies' = resolved_lazies in
+		(fun () ->
+			l <- l';
+			resolved_lazies <- resolved_lazies';
+		)
+
+	method get_list =
+		l
+
+	method cache_type_imports =
+		let rec loop = function
+		| [] ->
+			()
+		| res :: l ->
+			(* loop first to retain correct order *)
+			loop l;
+			match res.r_kind with
+			| RTypeImport(alias,mt) ->
+				type_import_cache <- StringMap.add alias (mt,res.r_pos) type_import_cache;
+			| _ ->
+				()
+		in
+		if not cached_type_imports then begin
+			cached_type_imports <- true;
+			type_import_cache <- StringMap.empty;
+			loop l
+		end;
+
+	method find_type_import alias =
+		self#cache_type_imports;
+		StringMap.find alias type_import_cache
+
+	method find_type_import_weirdly pack name =
+		let rec find l = match l with
+			| [] ->
+				raise Not_found
+			| {r_kind = RTypeImport(alias,mt); r_pos = p} :: l ->
+				if  t_path mt = (pack,name) then (mt,p) else find l
+			| _ :: l ->
+				find l
+		in
+		find l
+
+	method extract_type_imports =
+		ExtList.List.filter_map (fun res -> match res.r_kind with
+			| RTypeImport(_,mt) ->
+				Some (mt,res.r_pos)
+			| _ ->
+				None
+		) l
+
+	method extract_field_imports =
+		self#resolve_lazies;
+		let l = List.fold_left (fun acc res -> match res.r_kind with
+			| RClassFieldImport(alias,c,cf) ->
+				PMap.add alias ((TClassDecl c),cf.cf_name,res.r_pos) acc
+			| RClassStatics c ->
+				List.fold_left (fun acc cf ->
+					begin match as_importable_static c cf null_pos with
+					| Some (alias,res) ->
+						PMap.add alias ((TClassDecl c),cf.cf_name,res.r_pos) acc
+					| _ ->
+						acc
+					end
+				) acc c.cl_ordered_statics
+			| _ ->
+				acc
+		) PMap.empty l in
+		l
+
+	method extract_wildcard_packages =
+		ExtList.List.filter_map (fun res -> match res.r_kind with
+			| RWildcardPackage sl ->
+				Some (sl,res.r_pos)
+			| _ ->
+				None
+		) l
+end

+ 1 - 3
src/context/sourcemaps.ml

@@ -1,7 +1,5 @@
 open Extlib_leftovers
 open Extlib_leftovers
 open Globals
 open Globals
-open Ast
-open Lexer
 open Common
 open Common
 
 
 (**
 (**
@@ -299,4 +297,4 @@ let set_sourcemap_pointer (builder:sourcemap_builder option) (pointer:sm_node op
 		| Some builder ->
 		| Some builder ->
 			match pointer with
 			match pointer with
 				| Some node -> builder#seek node
 				| Some node -> builder#seek node
-				| None -> ()
+				| None -> ()

+ 126 - 81
src/context/typecore.ml

@@ -22,7 +22,7 @@ open Ast
 open Common
 open Common
 open Type
 open Type
 open Error
 open Error
-open DisplayTypes
+open Resolution
 
 
 type type_patch = {
 type type_patch = {
 	mutable tp_type : complex_type option;
 	mutable tp_type : complex_type option;
@@ -60,15 +60,20 @@ type typer_pass =
 
 
 type typer_module = {
 type typer_module = {
 	curmod : module_def;
 	curmod : module_def;
-	mutable module_imports : (module_type * pos) list;
+	import_resolution : resolution_list;
+	mutable own_resolution : resolution_list option;
+	mutable enum_with_type : module_type option;
 	mutable module_using : (tclass * pos) list;
 	mutable module_using : (tclass * pos) list;
-	mutable module_globals : (string, (module_type * string * pos)) PMap.t;
-	mutable wildcard_packages : (string list * pos) list;
 	mutable import_statements : import list;
 	mutable import_statements : import list;
 }
 }
 
 
+type delay = {
+	delay_pass : typer_pass;
+	delay_functions : (unit -> unit) list;
+}
+
 type typer_globals = {
 type typer_globals = {
-	mutable delayed : (typer_pass * (unit -> unit) list) list;
+	mutable delayed : delay list;
 	mutable debug_delayed : (typer_pass * ((unit -> unit) * string * typer) list) list;
 	mutable debug_delayed : (typer_pass * ((unit -> unit) * string * typer) list) list;
 	doinline : bool;
 	doinline : bool;
 	retain_meta : bool;
 	retain_meta : bool;
@@ -76,7 +81,6 @@ type typer_globals = {
 	mutable macros : ((unit -> unit) * typer) option;
 	mutable macros : ((unit -> unit) * typer) option;
 	mutable std : module_def;
 	mutable std : module_def;
 	type_patches : (path, (string * bool, type_patch) Hashtbl.t * type_patch) Hashtbl.t;
 	type_patches : (path, (string * bool, type_patch) Hashtbl.t * type_patch) Hashtbl.t;
-	mutable global_metadata : (string list * metadata_entry * (bool * bool * bool)) list;
 	mutable module_check_policies : (string list * module_check_policy list * bool) list;
 	mutable module_check_policies : (string list * module_check_policy list * bool) list;
 	mutable global_using : (tclass * pos) list;
 	mutable global_using : (tclass * pos) list;
 	(* Indicates that Typer.create() finished building this instance *)
 	(* Indicates that Typer.create() finished building this instance *)
@@ -86,7 +90,6 @@ type typer_globals = {
 	functional_interface_lut : (path,tclass_field) lookup;
 	functional_interface_lut : (path,tclass_field) lookup;
 	(* api *)
 	(* api *)
 	do_inherit : typer -> Type.tclass -> pos -> (bool * placed_type_path) -> bool;
 	do_inherit : typer -> Type.tclass -> pos -> (bool * placed_type_path) -> bool;
-	do_create : Common.context -> typer;
 	do_macro : typer -> macro_mode -> path -> string -> expr list -> pos -> expr option;
 	do_macro : typer -> macro_mode -> path -> string -> expr list -> pos -> expr option;
 	do_load_macro : typer -> bool -> path -> string -> pos -> ((string * bool * t) list * t * tclass * Type.tclass_field);
 	do_load_macro : typer -> bool -> path -> string -> pos -> ((string * bool * t) list * t * tclass * Type.tclass_field);
 	do_load_module : typer -> path -> pos -> module_def;
 	do_load_module : typer -> path -> pos -> module_def;
@@ -199,7 +202,7 @@ type dot_path_part = {
 
 
 exception Forbid_package of (string * path * pos) * pos list * string
 exception Forbid_package of (string * path * pos) * pos list * string
 
 
-exception WithTypeError of error_msg * pos * int (* depth *)
+exception WithTypeError of error
 
 
 let memory_marker = [|Unix.time()|]
 let memory_marker = [|Unix.time()|]
 
 
@@ -214,6 +217,8 @@ let analyzer_run_on_expr_ref : (Common.context -> string -> texpr -> texpr) ref
 let cast_or_unify_raise_ref : (typer -> ?uctx:unification_context option -> Type.t -> texpr -> pos -> texpr) ref = ref (fun _ ?uctx _ _ _ -> assert false)
 let cast_or_unify_raise_ref : (typer -> ?uctx:unification_context option -> Type.t -> texpr -> pos -> texpr) ref = ref (fun _ ?uctx _ _ _ -> assert false)
 let type_generic_function_ref : (typer -> field_access -> (unit -> texpr) field_call_candidate -> WithType.t -> pos -> texpr) ref = ref (fun _ _ _ _ _ -> assert false)
 let type_generic_function_ref : (typer -> field_access -> (unit -> texpr) field_call_candidate -> WithType.t -> pos -> texpr) ref = ref (fun _ _ _ _ _ -> assert false)
 
 
+let create_context_ref : (Common.context -> ((unit -> unit) * typer) option -> typer) ref = ref (fun _ -> assert false)
+
 let pass_name = function
 let pass_name = function
 	| PBuildModule -> "build-module"
 	| PBuildModule -> "build-module"
 	| PBuildClass -> "build-class"
 	| PBuildClass -> "build-class"
@@ -229,6 +234,24 @@ let warning ?(depth=0) ctx w msg p =
 
 
 let make_call ctx e el t p = (!make_call_ref) ctx e el t p
 let make_call ctx e el t p = (!make_call_ref) ctx e el t p
 
 
+let make_static_call_gen ctx c cf el map p =
+	let monos = Monomorph.spawn_constrained_monos map cf.cf_params in
+	let t = map (apply_params cf.cf_params monos cf.cf_type) in
+	match follow t with
+	| TFun(args,ret) ->
+		let ethis = Texpr.Builder.make_static_this c p in
+		let ef = mk (TField(ethis,FStatic(c,cf))) t p in
+		make_call ctx ef el ret p
+	| t ->
+		raise_typing_error (s_type (print_context()) t ^ " cannot be called") p
+
+let make_static_class_call ctx c cf el p =
+	make_static_call_gen ctx c cf el (fun t -> t) p
+
+let make_static_abstract_call ctx a tl c cf el p =
+	let map = apply_params a.a_params tl in
+	make_static_call_gen ctx c cf el map p
+
 let type_expr ?(mode=MGet) ctx e with_type = (!type_expr_ref) ~mode ctx e with_type
 let type_expr ?(mode=MGet) ctx e with_type = (!type_expr_ref) ~mode ctx e with_type
 
 
 let unify_min ctx el = (!unify_min_ref) ctx el
 let unify_min ctx el = (!unify_min_ref) ctx el
@@ -242,27 +265,21 @@ let spawn_monomorph' ctx p =
 let spawn_monomorph ctx p =
 let spawn_monomorph ctx p =
 	TMono (spawn_monomorph' ctx p)
 	TMono (spawn_monomorph' ctx p)
 
 
-let make_static_this c p =
-	let ta = mk_anon ~fields:c.cl_statics (ref (Statics c)) in
-	mk (TTypeExpr (TClassDecl c)) ta p
-
-let make_static_field_access c cf t p =
-	let ethis = make_static_this c p in
-	mk (TField (ethis,(FStatic (c,cf)))) t p
-
-let make_static_call ctx c cf map args t p =
-	let monos = List.map (fun _ -> spawn_monomorph ctx p) cf.cf_params in
-	let map t = map (apply_params cf.cf_params monos t) in
-	let ef = make_static_field_access c cf (map cf.cf_type) p in
-	make_call ctx ef args (map t) p
+let raise_with_type_error ?(depth = 0) msg p =
+	raise (WithTypeError (make_error ~depth (Custom msg) p))
 
 
 let raise_or_display ctx l p =
 let raise_or_display ctx l p =
 	if ctx.untyped then ()
 	if ctx.untyped then ()
-	else if ctx.in_call_args then raise (WithTypeError(Unify l,p,0))
-	else located_display_error ctx.com (error_msg p (Unify l))
+	else if ctx.in_call_args then raise (WithTypeError (make_error (Unify l) p))
+	else display_error_ext ctx.com (make_error (Unify l) p)
+
+let raise_or_display_error ctx err =
+	if ctx.untyped then ()
+	else if ctx.in_call_args then raise (WithTypeError err)
+	else display_error_ext ctx.com err
 
 
 let raise_or_display_message ctx msg p =
 let raise_or_display_message ctx msg p =
-	if ctx.in_call_args then raise (WithTypeError (Custom msg,p,0))
+	if ctx.in_call_args then raise_with_type_error msg p
 	else display_error ctx.com msg p
 	else display_error ctx.com msg p
 
 
 let unify ctx t1 t2 p =
 let unify ctx t1 t2 p =
@@ -278,7 +295,7 @@ let unify_raise_custom uctx t1 t2 p =
 	with
 	with
 		Unify_error l ->
 		Unify_error l ->
 			(* no untyped check *)
 			(* no untyped check *)
-			raise (Error (Unify l,p,0))
+			raise_error_msg (Unify l) p
 
 
 let unify_raise = unify_raise_custom default_unification_context
 let unify_raise = unify_raise_custom default_unification_context
 
 
@@ -336,8 +353,11 @@ let check_module_path ctx (pack,name) p =
 	try
 	try
 		List.iter (fun part -> Path.check_package_name part) pack;
 		List.iter (fun part -> Path.check_package_name part) pack;
 	with Failure msg ->
 	with Failure msg ->
-		display_error ctx.com ("\"" ^ (StringHelper.s_escape (String.concat "." pack)) ^ "\" is not a valid package name:") p;
-		display_error ctx.com msg p
+		display_error_ext ctx.com (make_error
+			~sub:[make_error (Custom msg) p]
+			(Custom ("\"" ^ (StringHelper.s_escape (String.concat "." pack)) ^ "\" is not a valid package name:"))
+			p
+		)
 
 
 let check_local_variable_name ctx name origin p =
 let check_local_variable_name ctx name origin p =
 	match name with
 	match name with
@@ -361,32 +381,42 @@ let add_local_with_origin ctx origin n t p =
 let gen_local_prefix = "`"
 let gen_local_prefix = "`"
 
 
 let gen_local ctx t p =
 let gen_local ctx t p =
-	add_local ctx VGenerated "`" t p
+	add_local ctx VGenerated gen_local_prefix t p
 
 
-let is_gen_local v =
-	String.unsafe_get v.v_name 0 = String.unsafe_get gen_local_prefix 0
+let is_gen_local v = match v.v_kind with
+	| VGenerated ->
+		true
+	| _ ->
+		false
+
+let make_delay pass fl = {
+	delay_pass = pass;
+	delay_functions = fl;
+}
 
 
 let delay ctx p f =
 let delay ctx p f =
 	let rec loop = function
 	let rec loop = function
-		| [] -> [p,[f]]
-		| (p2,l) :: rest ->
-			if p2 = p then
-				(p, f :: l) :: rest
-			else if p2 < p then
-				(p2,l) :: loop rest
+		| [] ->
+			[make_delay p [f]]
+		| delay :: rest ->
+			if delay.delay_pass = p then
+				(make_delay p (f :: delay.delay_functions)) :: rest
+			else if delay.delay_pass < p then
+				delay :: loop rest
 			else
 			else
-				(p,[f]) :: (p2,l) :: rest
+				(make_delay p [f]) :: delay :: rest
 	in
 	in
 	ctx.g.delayed <- loop ctx.g.delayed
 	ctx.g.delayed <- loop ctx.g.delayed
 
 
 let delay_late ctx p f =
 let delay_late ctx p f =
 	let rec loop = function
 	let rec loop = function
-		| [] -> [p,[f]]
-		| (p2,l) :: rest ->
-			if p2 <= p then
-				(p2,l) :: loop rest
+		| [] ->
+			[make_delay p [f]]
+		| delay :: rest ->
+			if delay.delay_pass <= p then
+				delay :: loop rest
 			else
 			else
-				(p,[f]) :: (p2,l) :: rest
+				(make_delay p [f]) :: delay :: rest
 	in
 	in
 	ctx.g.delayed <- loop ctx.g.delayed
 	ctx.g.delayed <- loop ctx.g.delayed
 
 
@@ -398,12 +428,12 @@ let delay_if_mono ctx p t f = match follow t with
 
 
 let rec flush_pass ctx p (where:string) =
 let rec flush_pass ctx p (where:string) =
 	match ctx.g.delayed with
 	match ctx.g.delayed with
-	| (p2,l) :: rest when p2 <= p ->
-		(match l with
+	| delay :: rest when delay.delay_pass <= p ->
+		(match delay.delay_functions with
 		| [] ->
 		| [] ->
 			ctx.g.delayed <- rest;
 			ctx.g.delayed <- rest;
 		| f :: l ->
 		| f :: l ->
-			ctx.g.delayed <- (p2,l) :: rest;
+			ctx.g.delayed <- (make_delay delay.delay_pass l) :: rest;
 			f());
 			f());
 		flush_pass ctx p where
 		flush_pass ctx p where
 	| _ ->
 	| _ ->
@@ -422,8 +452,8 @@ let exc_protect ?(force=true) ctx f (where:string) =
 			r := lazy_available t;
 			r := lazy_available t;
 			t
 			t
 		with
 		with
-			| Error (m,p,depth) ->
-				raise (Fatal_error ((error_msg p m),depth))
+			| Error e ->
+				raise (Fatal_error e)
 	);
 	);
 	if force then delay ctx PForce (fun () -> ignore(lazy_type r));
 	if force then delay ctx PForce (fun () -> ignore(lazy_type r));
 	r
 	r
@@ -455,8 +485,18 @@ let is_removable_field com f =
 			| _ -> false)
 			| _ -> false)
 	)
 	)
 
 
+let is_forced_inline c cf =
+	match c with
+	| Some { cl_kind = KAbstractImpl _ } -> true
+	| Some c when has_class_flag c CExtern -> true
+	| _ when has_class_field_flag cf CfExtern -> true
+	| _ -> false
+
+let needs_inline ctx c cf =
+	cf.cf_kind = Method MethInline && ctx.allow_inline && (ctx.g.doinline || is_forced_inline c cf)
+
 (** checks if we can access to a given class field using current context *)
 (** checks if we can access to a given class field using current context *)
-let rec can_access ctx c cf stat =
+let can_access ctx c cf stat =
 	if (has_class_field_flag cf CfPublic) then
 	if (has_class_field_flag cf CfPublic) then
 		true
 		true
 	else if c == ctx.curclass then
 	else if c == ctx.curclass then
@@ -592,7 +632,7 @@ let merge_core_doc ctx mt =
 
 
 let field_to_type_path com e =
 let field_to_type_path com e =
 	let rec loop e pack name = match e with
 	let rec loop e pack name = match e with
-		| EField(e,f,_),p when Char.lowercase (String.get f 0) <> String.get f 0 -> (match name with
+		| EField(e,f,_),p when Char.lowercase_ascii (String.get f 0) <> String.get f 0 -> (match name with
 			| [] | _ :: [] ->
 			| [] | _ :: [] ->
 				loop e pack (f :: name)
 				loop e pack (f :: name)
 			| _ -> (* too many name paths *)
 			| _ -> (* too many name paths *)
@@ -604,7 +644,7 @@ let field_to_type_path com e =
 			let pack, name, sub = match name with
 			let pack, name, sub = match name with
 				| [] ->
 				| [] ->
 					let fchar = String.get f 0 in
 					let fchar = String.get f 0 in
-					if Char.uppercase fchar = fchar then
+					if Char.uppercase_ascii fchar = fchar then
 						pack, f, None
 						pack, f, None
 					else begin
 					else begin
 						display_error com "A class name must start with an uppercase letter" (snd e);
 						display_error com "A class name must start with an uppercase letter" (snd e);
@@ -654,12 +694,12 @@ let s_field_call_candidate fcc =
 let relative_path ctx file =
 let relative_path ctx file =
 	let slashes path = String.concat "/" (ExtString.String.nsplit path "\\") in
 	let slashes path = String.concat "/" (ExtString.String.nsplit path "\\") in
 	let fpath = slashes (Path.get_full_path file) in
 	let fpath = slashes (Path.get_full_path file) in
-	let fpath_lower = String.lowercase fpath in
+	let fpath_lower = String.lowercase_ascii fpath in
 	let flen = String.length fpath_lower in
 	let flen = String.length fpath_lower in
 	let rec loop = function
 	let rec loop = function
 		| [] -> file
 		| [] -> file
 		| path :: l ->
 		| path :: l ->
-			let spath = String.lowercase (slashes path) in
+			let spath = String.lowercase_ascii (slashes path) in
 			let slen = String.length spath in
 			let slen = String.length spath in
 			if slen > 0 && slen < flen && String.sub fpath_lower 0 slen = spath then String.sub fpath slen (flen - slen) else loop l
 			if slen > 0 && slen < flen && String.sub fpath_lower 0 slen = spath then String.sub fpath slen (flen - slen) else loop l
 	in
 	in
@@ -703,14 +743,13 @@ let get_next_stored_typed_expr_id =
 	let uid = ref 0 in
 	let uid = ref 0 in
 	(fun() -> incr uid; !uid)
 	(fun() -> incr uid; !uid)
 
 
-let get_stored_typed_expr com id =
-	let e = com.stored_typed_exprs#find id in
-	Texpr.duplicate_tvars e
+let make_stored_id_expr id p =
+	(EConst (Int (string_of_int id, None))), p
 
 
 let store_typed_expr com te p =
 let store_typed_expr com te p =
 	let id = get_next_stored_typed_expr_id() in
 	let id = get_next_stored_typed_expr_id() in
 	com.stored_typed_exprs#add id te;
 	com.stored_typed_exprs#add id te;
-	let eid = (EConst (Int (string_of_int id, None))), p in
+	let eid = make_stored_id_expr id p in
 	id,((EMeta ((Meta.StoredTypedExpr,[],null_pos), eid)),p)
 	id,((EMeta ((Meta.StoredTypedExpr,[],null_pos), eid)),p)
 
 
 let push_this ctx e = match e.eexpr with
 let push_this ctx e = match e.eexpr with
@@ -720,29 +759,35 @@ let push_this ctx e = match e.eexpr with
 	let id,er = store_typed_expr ctx.com e e.epos in
 	let id,er = store_typed_expr ctx.com e e.epos in
 	er,fun () -> ctx.com.stored_typed_exprs#remove id
 	er,fun () -> ctx.com.stored_typed_exprs#remove id
 
 
+let create_deprecation_context ctx = {
+	(DeprecationCheck.create_context ctx.com) with
+	class_meta = ctx.curclass.cl_meta;
+	field_meta = ctx.curfield.cf_meta;
+}
+
 (* -------------- debug functions to activate when debugging typer passes ------------------------------- *)
 (* -------------- debug functions to activate when debugging typer passes ------------------------------- *)
 (*/*
 (*/*
 
 
 let delay_tabs = ref ""
 let delay_tabs = ref ""
 
 
-let context_ident ctx =
-	if Common.defined ctx.com Common.Define.CoreApi then
+let context_ident com =
+	if Common.defined com Common.Define.CoreApi then
 		" core "
 		" core "
-	else if Common.defined ctx.com Common.Define.Macro then
+	else if Common.defined com Common.Define.Macro then
 		"macro "
 		"macro "
 	else
 	else
 		"  out "
 		"  out "
 
 
-let debug ctx str =
-	if Common.raw_defined ctx.com "cdebug" then begin
-		let s = (context_ident ctx ^ string_of_int (String.length !delay_tabs) ^ " " ^ !delay_tabs ^ str) in
-		match ctx.com.json_out with
+let debug com str =
+	if Common.raw_defined com "cdebug" then begin
+		let s = (context_ident com ^ string_of_int (String.length !delay_tabs) ^ " " ^ !delay_tabs ^ str) in
+		match com.json_out with
 		| None -> print_endline s
 		| None -> print_endline s
-		| Some _ -> DynArray.add ctx.com.pass_debug_messages s
+		| Some _ -> DynArray.add com.pass_debug_messages s
 	end
 	end
 
 
 let init_class_done ctx =
 let init_class_done ctx =
-	debug ctx ("init_class_done " ^ s_type_path ctx.curclass.cl_path);
+	debug ctx.com ("init_class_done " ^ s_type_path ctx.curclass.cl_path);
 	init_class_done ctx
 	init_class_done ctx
 
 
 let ctx_pos ctx =
 let ctx_pos ctx =
@@ -769,7 +814,7 @@ let delay ctx p f =
 				(p,[f,inf,ctx]) :: (p2,l) :: rest
 				(p,[f,inf,ctx]) :: (p2,l) :: rest
 	in
 	in
 	ctx.g.debug_delayed <- loop ctx.g.debug_delayed;
 	ctx.g.debug_delayed <- loop ctx.g.debug_delayed;
-	debug ctx ("add " ^ inf)
+	debug ctx.com ("add " ^ inf)
 
 
 let delay_late ctx p f =
 let delay_late ctx p f =
 	let inf = pass_infos ctx p in
 	let inf = pass_infos ctx p in
@@ -782,7 +827,7 @@ let delay_late ctx p f =
 				(p,[f,inf,ctx]) :: (p2,l) :: rest
 				(p,[f,inf,ctx]) :: (p2,l) :: rest
 	in
 	in
 	ctx.g.debug_delayed <- loop ctx.g.debug_delayed;
 	ctx.g.debug_delayed <- loop ctx.g.debug_delayed;
-	debug ctx ("add late " ^ inf)
+	debug ctx.com ("add late " ^ inf)
 
 
 let pending_passes ctx =
 let pending_passes ctx =
 	let rec loop acc = function
 	let rec loop acc = function
@@ -793,28 +838,28 @@ let pending_passes ctx =
 	| [] -> ""
 	| [] -> ""
 	| l -> " ??PENDING[" ^ String.concat ";" (List.map (fun (_,i,_) -> i) l) ^ "]"
 	| l -> " ??PENDING[" ^ String.concat ";" (List.map (fun (_,i,_) -> i) l) ^ "]"
 
 
-let display_error ctx.com msg p =
-	debug ctx ("ERROR " ^ msg);
-	display_error ctx.com msg p
+let display_error com ?(depth=0) msg p =
+	debug com ("ERROR " ^ msg);
+	display_error com ~depth msg p
 
 
-let located_display_error ctx.com msg =
-	debug ctx ("ERROR " ^ msg);
-	located_display_error ctx.com msg
+let display_error_ext com err =
+	debug com ("ERROR " ^ (error_msg err.err_message));
+	display_error_ext com err
 
 
 let make_pass ?inf ctx f =
 let make_pass ?inf ctx f =
 	let inf = (match inf with None -> pass_infos ctx ctx.pass | Some inf -> inf) in
 	let inf = (match inf with None -> pass_infos ctx ctx.pass | Some inf -> inf) in
 	(fun v ->
 	(fun v ->
-		debug ctx ("run " ^ inf ^ pending_passes ctx);
+		debug ctx.com ("run " ^ inf ^ pending_passes ctx);
 		let old = !delay_tabs in
 		let old = !delay_tabs in
 		delay_tabs := !delay_tabs ^ "\t";
 		delay_tabs := !delay_tabs ^ "\t";
 		let t = (try
 		let t = (try
 			f v
 			f v
 		with
 		with
-			| Fatal_error (e,p) ->
+			| Fatal_error _ as exc ->
 				delay_tabs := old;
 				delay_tabs := old;
-				raise (Fatal_error (e,p))
+				raise exc
 			| exc when not (Common.raw_defined ctx.com "stack") ->
 			| exc when not (Common.raw_defined ctx.com "stack") ->
-				debug ctx ("FATAL " ^ Printexc.to_string exc);
+				debug ctx.com ("FATAL " ^ Printexc.to_string exc);
 				delay_tabs := old;
 				delay_tabs := old;
 				raise exc
 				raise exc
 		) in
 		) in
@@ -841,11 +886,11 @@ let rec flush_pass ctx p where =
 	match ctx.g.debug_delayed with
 	match ctx.g.debug_delayed with
 	| (p2,_) :: _ when p2 <= p ->
 	| (p2,_) :: _ when p2 <= p ->
 		let old = !delay_tabs in
 		let old = !delay_tabs in
-		debug ctx ("flush " ^ pass_name p ^ "(" ^ where ^ ")");
+		debug ctx.com ("flush " ^ pass_name p ^ "(" ^ where ^ ")");
 		delay_tabs := !delay_tabs ^ "\t";
 		delay_tabs := !delay_tabs ^ "\t";
 		loop();
 		loop();
 		delay_tabs := old;
 		delay_tabs := old;
-		debug ctx "flush-done";
+		debug ctx.com "flush-done";
 	| _ ->
 	| _ ->
 		()
 		()
 
 
@@ -860,8 +905,8 @@ let exc_protect ?(force=true) ctx f (where:string) =
 			r := lazy_available t;
 			r := lazy_available t;
 			t
 			t
 		with
 		with
-			| Error (m,p,depth) ->
-				raise (Fatal_error ((error_msg m),p,depth))
+			| Error e ->
+				raise (Fatal_error e)
 	));
 	));
 	if force then delay ctx PForce (fun () -> ignore(lazy_type r));
 	if force then delay ctx PForce (fun () -> ignore(lazy_type r));
 	r
 	r

+ 2 - 4
src/core/abstract.ml

@@ -1,6 +1,4 @@
-open Globals
 open Ast
 open Ast
-open Meta
 open TType
 open TType
 open TFunctions
 open TFunctions
 open TPrinting
 open TPrinting
@@ -83,7 +81,7 @@ let rec find_multitype_params a pl =
 				| EMeta((Meta.Custom ":followWithAbstracts",_,_),e1) ->
 				| EMeta((Meta.Custom ":followWithAbstracts",_,_),e1) ->
 					loop follow_with_abstracts e1;
 					loop follow_with_abstracts e1;
 				| _ ->
 				| _ ->
-					typing_error "Type parameter expected" (pos e)
+					raise_typing_error "Type parameter expected" (pos e)
 			in
 			in
 			loop (fun t -> t) e
 			loop (fun t -> t) e
 		) el;
 		) el;
@@ -124,7 +122,7 @@ and get_underlying_type ?(return_first=false) a pl =
 				if rec_stack_exists (fast_eq t) underlying_type_stack then begin
 				if rec_stack_exists (fast_eq t) underlying_type_stack then begin
 					let pctx = print_context() in
 					let pctx = print_context() in
 					let s = String.concat " -> " (List.map (fun t -> s_type pctx t) (List.rev (t :: underlying_type_stack.rec_stack))) in
 					let s = String.concat " -> " (List.map (fun t -> s_type pctx t) (List.rev (t :: underlying_type_stack.rec_stack))) in
-					typing_error ("Abstract chain detected: " ^ s) a.a_pos
+					raise_typing_error ("Abstract chain detected: " ^ s) a.a_pos
 				end;
 				end;
 				get_underlying_type a tl
 				get_underlying_type a tl
 			| _ ->
 			| _ ->

+ 5 - 5
src/core/ast.ml

@@ -300,6 +300,7 @@ and access =
 	| AExtern
 	| AExtern
 	| AAbstract
 	| AAbstract
 	| AOverload
 	| AOverload
+	| AEnum
 
 
 and placed_access = access * pos
 and placed_access = access * pos
 
 
@@ -440,7 +441,7 @@ let gen_doc_text_opt = Option.map gen_doc_text
 
 
 let get_own_doc_opt = Option.map_default (fun d -> d.doc_own) None
 let get_own_doc_opt = Option.map_default (fun d -> d.doc_own) None
 
 
-let rec is_postfix (e,_) op = match op with
+let is_postfix (e,_) op = match op with
 	| Increment | Decrement | Not -> true
 	| Increment | Decrement | Not -> true
 	| Neg | NegBits | Spread -> false
 	| Neg | NegBits | Spread -> false
 
 
@@ -491,6 +492,7 @@ let s_access = function
 	| AExtern -> "extern"
 	| AExtern -> "extern"
 	| AAbstract -> "abstract"
 	| AAbstract -> "abstract"
 	| AOverload -> "overload"
 	| AOverload -> "overload"
+	| AEnum -> "enum"
 
 
 let s_placed_access (a,_) = s_access a
 let s_placed_access (a,_) = s_access a
 
 
@@ -1205,7 +1207,7 @@ module Expr = struct
 		Buffer.contents buf
 		Buffer.contents buf
 
 
 	let find_ident e =
 	let find_ident e =
-		let rec loop e = match fst e with
+		match fst e with
 			| EConst ct ->
 			| EConst ct ->
 				begin match ct with
 				begin match ct with
 				| Ident s ->
 				| Ident s ->
@@ -1215,8 +1217,6 @@ module Expr = struct
 				end
 				end
 			| _ ->
 			| _ ->
 				None
 				None
-		in
-		loop e
 end
 end
 
 
 let has_meta_option metas meta s =
 let has_meta_option metas meta s =
@@ -1258,4 +1258,4 @@ let get_meta_string meta key =
 		| (k,[EConst (String(name,_)),_],_) :: _ when k = key -> Some name
 		| (k,[EConst (String(name,_)),_],_) :: _ when k = key -> Some name
 		| _ :: l -> loop l
 		| _ :: l -> loop l
 	in
 	in
-	loop meta
+	loop meta

+ 8 - 2
src/core/define.ml

@@ -39,6 +39,7 @@ let get_documentation user_defines d =
 		| HasParam s -> params := s :: !params
 		| HasParam s -> params := s :: !params
 		| Platforms fl -> pfs := fl @ !pfs
 		| Platforms fl -> pfs := fl @ !pfs
 		| Link _ -> ()
 		| Link _ -> ()
+		| Deprecated _ -> ()
 	) flags;
 	) flags;
 	let params = (match List.rev !params with
 	let params = (match List.rev !params with
 		| [] -> ""
 		| [] -> ""
@@ -117,7 +118,7 @@ let get_signature def =
 			   Note that we should removed flags like use_rtti_doc here.
 			   Note that we should removed flags like use_rtti_doc here.
 			*)
 			*)
 			| "display" | "use_rtti_doc" | "macro_times" | "display_details" | "no_copt" | "display_stdin"
 			| "display" | "use_rtti_doc" | "macro_times" | "display_details" | "no_copt" | "display_stdin"
-			| "message_reporting" | "messages_log_file" | "messages_log_format" | "no_color"
+			| "message.reporting" | "message.log_file" | "message.log_format" | "message.no_color"
 			| "dump" | "dump_dependencies" | "dump_ignore_var_ids" -> acc
 			| "dump" | "dump_dependencies" | "dump_ignore_var_ids" -> acc
 			| _ -> (k ^ "=" ^ v) :: acc
 			| _ -> (k ^ "=" ^ v) :: acc
 		) def.values [] in
 		) def.values [] in
@@ -126,4 +127,9 @@ let get_signature def =
 		def.defines_signature <- Some s;
 		def.defines_signature <- Some s;
 		s
 		s
 
 
-let is_haxe3_compat def = raw_defined def "hx3compat"
+let deprecation_lut =
+	let h = Hashtbl.create 0 in
+	List.iter (fun (name,reason) ->
+		Hashtbl.add h name reason
+	) deprecated_defines;
+	h

+ 6 - 4
src/core/displayTypes.ml

@@ -1,8 +1,6 @@
 open Globals
 open Globals
-open Path
 open Ast
 open Ast
 open Type
 open Type
-open Json
 open Genjson
 open Genjson
 
 
 module SymbolKind = struct
 module SymbolKind = struct
@@ -198,6 +196,7 @@ module DisplayMode = struct
 		dms_inline : bool;
 		dms_inline : bool;
 		dms_display_file_policy : display_file_policy;
 		dms_display_file_policy : display_file_policy;
 		dms_exit_during_typing : bool;
 		dms_exit_during_typing : bool;
+		dms_populate_cache : bool;
 		dms_per_file : bool;
 		dms_per_file : bool;
 	}
 	}
 
 
@@ -210,6 +209,7 @@ module DisplayMode = struct
 		dms_inline = false;
 		dms_inline = false;
 		dms_display_file_policy = DFPOnly;
 		dms_display_file_policy = DFPOnly;
 		dms_exit_during_typing = true;
 		dms_exit_during_typing = true;
+		dms_populate_cache = false;
 		dms_per_file = false;
 		dms_per_file = false;
 	}
 	}
 
 
@@ -222,6 +222,7 @@ module DisplayMode = struct
 		dms_inline = true;
 		dms_inline = true;
 		dms_display_file_policy = DFPNo;
 		dms_display_file_policy = DFPNo;
 		dms_exit_during_typing = false;
 		dms_exit_during_typing = false;
+		dms_populate_cache = true;
 		dms_per_file = false;
 		dms_per_file = false;
 	}
 	}
 
 
@@ -232,6 +233,7 @@ module DisplayMode = struct
 		| DMDefault | DMDefinition | DMTypeDefinition | DMPackage | DMHover | DMSignature -> settings
 		| DMDefault | DMDefinition | DMTypeDefinition | DMPackage | DMHover | DMSignature -> settings
 		| DMUsage _ | DMImplementation -> { settings with
 		| DMUsage _ | DMImplementation -> { settings with
 				dms_full_typing = true;
 				dms_full_typing = true;
+				dms_populate_cache = !ServerConfig.populate_cache_from_display;
 				dms_force_macro_typing = true;
 				dms_force_macro_typing = true;
 				dms_display_file_policy = DFPAlso;
 				dms_display_file_policy = DFPAlso;
 				dms_exit_during_typing = false
 				dms_exit_during_typing = false
@@ -332,7 +334,7 @@ type diagnostics_context = {
 	mutable import_positions : (pos,bool ref) PMap.t;
 	mutable import_positions : (pos,bool ref) PMap.t;
 	mutable dead_blocks : (Path.UniqueKey.t,(pos * expr) list) Hashtbl.t;
 	mutable dead_blocks : (Path.UniqueKey.t,(pos * expr) list) Hashtbl.t;
 	mutable unresolved_identifiers : (string * pos * (string * CompletionItem.t * int) list) list;
 	mutable unresolved_identifiers : (string * pos * (string * CompletionItem.t * int) list) list;
-	mutable diagnostics_messages : (string * pos * MessageKind.t * MessageSeverity.t * int (* depth *)) list;
+	mutable diagnostics_messages : diagnostic list;
 	mutable missing_fields : (pos,(module_type * (missing_fields_diagnostics list ref))) PMap.t;
 	mutable missing_fields : (pos,(module_type * (missing_fields_diagnostics list ref))) PMap.t;
 }
 }
 
 
@@ -344,4 +346,4 @@ type display_exception_kind =
 	| DisplayPositions of pos list
 	| DisplayPositions of pos list
 	| DisplayFields of fields_result
 	| DisplayFields of fields_result
 	| DisplayPackage of string list
 	| DisplayPackage of string list
-	| DisplayNoResult
+	| DisplayNoResult

+ 51 - 35
src/core/error.ml

@@ -17,7 +17,6 @@ and error_msg =
 	| Unify of unify_error list
 	| Unify of unify_error list
 	| Custom of string
 	| Custom of string
 	| Unknown_ident of string
 	| Unknown_ident of string
-	| Stack of (error_msg * Globals.pos) list
 	| Call_error of call_error
 	| Call_error of call_error
 	| No_constructor of module_type
 	| No_constructor of module_type
 	| Abstract_class of module_type
 	| Abstract_class of module_type
@@ -26,8 +25,31 @@ and type_not_found_reason =
 	| Private_type
 	| Private_type
 	| Not_defined
 	| Not_defined
 
 
-exception Fatal_error of Globals.located * int (* depth *)
-exception Error of error_msg * Globals.pos * int (* depth *)
+type error = {
+	err_message : error_msg;
+	err_pos : pos;
+	(* TODO Should probably be deprecated at some point and be derived from err_sub *)
+	err_depth : int;
+	(* Reverse list of sub errors. Use Error.recurse_error to handle an error and its sub errors with depth. *)
+	err_sub : error list;
+	err_from_macro : bool;
+}
+
+let make_error ?(depth = 0) ?(from_macro = false) ?(sub = []) msg p = {
+	err_message = msg;
+	err_pos = p;
+	err_depth = depth;
+	err_from_macro = from_macro;
+	err_sub = sub;
+}
+
+let rec recurse_error ?(depth = 0) cb err =
+	let depth = if depth > 0 then depth else err.err_depth in
+	cb depth err;
+	List.iter (recurse_error ~depth:(depth+1) cb) (List.rev err.err_sub);
+
+exception Fatal_error of error
+exception Error of error
 
 
 let string_source t = match follow t with
 let string_source t = match follow t with
 	| TInst(c,tl) -> PMap.foldi (fun s _ acc -> s :: acc) (TClass.get_all_fields c tl) []
 	| TInst(c,tl) -> PMap.foldi (fun s _ acc -> s :: acc) (TClass.get_all_fields c tl) []
@@ -43,9 +65,6 @@ let short_type ctx t =
 	Should be called for each complementary error message.
 	Should be called for each complementary error message.
 *)
 *)
 let compl_msg s = "... " ^ s
 let compl_msg s = "... " ^ s
-let rec compl_located_msg = function
-	 | Message (s,p) -> Message (compl_msg s,p)
-	 | Stack stack -> Stack (List.map compl_located_msg stack)
 
 
 let unify_error_msg ctx err = match err with
 let unify_error_msg ctx err = match err with
 	| Cannot_unify (t1,t2) ->
 	| Cannot_unify (t1,t2) ->
@@ -191,7 +210,7 @@ module BetterErrors = struct
 		| TAnon a ->
 		| TAnon a ->
 			begin
 			begin
 				match !(a.a_status) with
 				match !(a.a_status) with
-				| Statics c -> Printf.sprintf "{ Statics %s }" (s_type_path c.cl_path)
+				| ClassStatics c -> Printf.sprintf "{ ClassStatics %s }" (s_type_path c.cl_path)
 				| EnumStatics e -> Printf.sprintf "{ EnumStatics %s }" (s_type_path e.e_path)
 				| EnumStatics e -> Printf.sprintf "{ EnumStatics %s }" (s_type_path e.e_path)
 				| AbstractStatics a -> Printf.sprintf "{ AbstractStatics %s }" (s_type_path a.a_path)
 				| AbstractStatics a -> Printf.sprintf "{ AbstractStatics %s }" (s_type_path a.a_path)
 				| _ ->
 				| _ ->
@@ -256,7 +275,7 @@ module BetterErrors = struct
 				let s1,s2 = loop() in
 				let s1,s2 = loop() in
 				Printf.sprintf "(...) -> %s" s1,Printf.sprintf "(...) -> %s" s2
 				Printf.sprintf "(...) -> %s" s1,Printf.sprintf "(...) -> %s" s2
 			| TypeParameter i ->
 			| TypeParameter i ->
-				let rec get_params t = match t with
+				let get_params t = match t with
 					| TInst({cl_path = path},params) | TEnum({e_path = path},params) | TAbstract({a_path = path},params) | TType({t_path = path},params) ->
 					| TInst({cl_path = path},params) | TEnum({e_path = path},params) | TAbstract({a_path = path},params) | TType({t_path = path},params) ->
 						path,params
 						path,params
 					| _ ->
 					| _ ->
@@ -280,39 +299,36 @@ module BetterErrors = struct
 			Printf.sprintf "error: %s\nhave: %s\nwant: %s" (Buffer.contents message_buffer) slhs srhs
 			Printf.sprintf "error: %s\nhave: %s\nwant: %s" (Buffer.contents message_buffer) slhs srhs
 end
 end
 
 
-let rec error_msg p = function
-	| Module_not_found m -> located ("Type not found : " ^ s_type_path m) p
-	| Type_not_found (m,t,Private_type) -> located ("Cannot access private type " ^ t ^ " in module " ^ s_type_path m) p
-	| Type_not_found (m,t,Not_defined) -> located ("Module " ^ s_type_path m ^ " does not define type " ^ t) p
-	| Unify l -> located (BetterErrors.better_error_message l) p
-	| Unknown_ident s -> located ("Unknown identifier : " ^ s) p
-	| Custom s -> located s p
-	| Stack stack -> located_stack (List.map (fun (e,p) -> error_msg p e) stack)
-	| Call_error err -> s_call_error p err
-	| No_constructor mt -> located (s_type_path (t_infos mt).mt_path ^ " does not have a constructor") p
-	| Abstract_class mt -> located (s_type_path (t_infos mt).mt_path ^ " is abstract and cannot be constructed") p
+let rec error_msg = function
+	| Module_not_found m -> "Type not found : " ^ s_type_path m
+	| Type_not_found (m,t,Private_type) -> "Cannot access private type " ^ t ^ " in module " ^ s_type_path m
+	| Type_not_found (m,t,Not_defined) -> "Module " ^ s_type_path m ^ " does not define type " ^ t
+	| Unify l -> BetterErrors.better_error_message l
+	| Unknown_ident s -> "Unknown identifier : " ^ s
+	| Custom s -> s
+	| Call_error err -> s_call_error err
+	| No_constructor mt -> s_type_path (t_infos mt).mt_path ^ " does not have a constructor"
+	| Abstract_class mt -> s_type_path (t_infos mt).mt_path ^ " is abstract and cannot be constructed"
 
 
-and s_call_error p = function
+and s_call_error = function
 	| Not_enough_arguments tl ->
 	| Not_enough_arguments tl ->
 		let pctx = print_context() in
 		let pctx = print_context() in
-		located ("Not enough arguments, expected " ^ (String.concat ", " (List.map (fun (n,_,t) -> n ^ ":" ^ (short_type pctx t)) tl))) p
-	| Too_many_arguments -> located "Too many arguments" p
-	| Could_not_unify err -> error_msg p err
-	| Cannot_skip_non_nullable s -> located ("Cannot skip non-nullable argument " ^ s) p
+		"Not enough arguments, expected " ^ (String.concat ", " (List.map (fun (n,_,t) -> n ^ ":" ^ (short_type pctx t)) tl))
+	| Too_many_arguments -> "Too many arguments"
+	| Could_not_unify err -> error_msg err
+	| Cannot_skip_non_nullable s -> "Cannot skip non-nullable argument " ^ s
 
 
-let typing_error ?(depth=0) msg p = raise (Error (Custom msg,p,depth))
-let located_typing_error ?(depth=0) msg =
-	let err = match msg with
-		| Message (msg,p) -> Custom msg
-		| Stack _ -> Stack (List.map (fun (msg,p) -> (Custom msg,p)) (extract_located msg))
-	in
-	raise (Error (err,(extract_located_pos msg),depth))
+(* Global error helpers *)
+let raise_error err = raise (Error err)
+let raise_error_msg ?(depth = 0) msg p = raise_error (make_error ~depth msg p)
+let raise_msg ?(depth = 0) msg p = raise_error_msg ~depth (Custom msg) p
 
 
-let raise_typing_error ?(depth=0) err p = raise (Error(err,p,depth))
+let raise_typing_error ?(depth = 0) msg p = raise_msg ~depth msg p
+let raise_typing_error_ext err = raise_error err
 
 
 let error_require r p =
 let error_require r p =
 	if r = "" then
 	if r = "" then
-		typing_error "This field is not available with the current compilation flags" p
+		raise_typing_error "This field is not available with the current compilation flags" p
 	else
 	else
 	let r = if r = "sys" then
 	let r = if r = "sys" then
 		"a system platform (php,neko,cpp,etc.)"
 		"a system platform (php,neko,cpp,etc.)"
@@ -323,6 +339,6 @@ let error_require r p =
 	with _ ->
 	with _ ->
 		"'" ^ r ^ "' to be enabled"
 		"'" ^ r ^ "' to be enabled"
 	in
 	in
-	typing_error ("Accessing this field requires " ^ r) p
+	raise_typing_error ("Accessing this field requires " ^ r) p
 
 
-let invalid_assign p = typing_error "Invalid assign" p
+let invalid_assign p = raise_typing_error "Invalid assign" p

+ 68 - 29
src/core/globals.ml

@@ -5,11 +5,8 @@ type pos = {
 }
 }
 
 
 type path = string list * string
 type path = string list * string
-type located =
-	| Message of string * pos
-	| Stack of located list
 
 
-module IntMap = Ptmap
+module IntMap = Map.Make(struct type t = int let compare i1 i2 = i2 - i1 end)
 module StringMap = Map.Make(struct type t = string let compare = String.compare end)
 module StringMap = Map.Make(struct type t = string let compare = String.compare end)
 module Int32Map = Map.Make(struct type t = Int32.t let compare = Int32.compare end)
 module Int32Map = Map.Make(struct type t = Int32.t let compare = Int32.compare end)
 
 
@@ -25,31 +22,50 @@ type platform =
 	| Python
 	| Python
 	| Hl
 	| Hl
 	| Eval
 	| Eval
+	| CustomTarget of string
 
 
-let version = 4300
+let version = 5000
 let version_major = version / 1000
 let version_major = version / 1000
 let version_minor = (version mod 1000) / 100
 let version_minor = (version mod 1000) / 100
 let version_revision = (version mod 100)
 let version_revision = (version mod 100)
-let version_pre = None
+let version_pre = Some "alpha.1"
 
 
 let null_pos = { pfile = "?"; pmin = -1; pmax = -1 }
 let null_pos = { pfile = "?"; pmin = -1; pmax = -1 }
 
 
-let located msg p = Message (msg,p)
-let located_stack stack = Stack stack
-
-let rec extract_located = function
-	| Message (msg,p) -> [(msg, p)]
-	| Stack stack -> List.fold_left (fun acc s -> acc @ (extract_located s)) [] stack
-
-let rec relocate msg p = match msg with
-	| Message (msg,_) -> Message (msg,p)
-	| Stack [] -> Stack []
-	| Stack (hd :: tl) -> Stack ((relocate hd p) :: tl)
-
-let rec extract_located_pos = function
-	| Message (_,p) -> p
-	| Stack [] -> null_pos
-	| Stack (hd :: _) -> extract_located_pos hd
+let no_color = false
+let c_reset = if no_color then "" else "\x1b[0m"
+let c_dim = if no_color then "" else "\x1b[2m"
+
+let loc_short (loc:Printexc.location) =
+	Printf.sprintf "%s:%d" loc.filename loc.line_number
+
+let loc_to_string (loc:Printexc.location) =
+	Printf.sprintf "%s, line %d, characters %d-%d" loc.filename loc.line_number loc.start_char loc.end_char
+
+let trace s =
+	let stack = Printexc.get_callstack 2 in
+	match Printexc.backtrace_slots stack with
+	| Some [|_; item |] ->
+		(match Printexc.Slot.location item with
+		| Some loc -> print_endline (Printf.sprintf "%s%s:%s %s" c_dim (loc_short loc) c_reset s)
+		| _ -> ())
+	| _ ->
+		()
+
+let trace_call_stack ?(n:int = 5) () =
+	assert (n >= 0);
+	let stack = Printexc.get_callstack (n+2) in
+	let len = Printexc.raw_backtrace_length stack - 1 in
+
+	let slot = Printexc.convert_raw_backtrace_slot (Printexc.get_raw_backtrace_slot stack 1) in
+	let loc = Printexc.Slot.location slot in
+	Option.may (fun loc -> print_endline (Printf.sprintf "%s%s:%s" c_dim (loc_short loc) c_reset)) loc;
+
+	for i = 2 to len do
+		let slot = Printexc.convert_raw_backtrace_slot (Printexc.get_raw_backtrace_slot stack i) in
+		let loc = Printexc.Slot.location slot in
+		Option.may (fun loc -> print_endline (Printf.sprintf "  called from %s" (loc_to_string loc))) loc;
+	done
 
 
 let macro_platform = ref Neko
 let macro_platform = ref Neko
 
 
@@ -57,6 +73,8 @@ let return_partial_type = ref false
 
 
 let is_windows = Sys.os_type = "Win32" || Sys.os_type = "Cygwin"
 let is_windows = Sys.os_type = "Win32" || Sys.os_type = "Cygwin"
 
 
+let max_custom_target_len = 16
+
 let platforms = [
 let platforms = [
 	Js;
 	Js;
 	Lua;
 	Lua;
@@ -83,6 +101,7 @@ let platform_name = function
 	| Python -> "python"
 	| Python -> "python"
 	| Hl -> "hl"
 	| Hl -> "hl"
 	| Eval -> "eval"
 	| Eval -> "eval"
+	| CustomTarget c -> c
 
 
 let parse_platform = function
 let parse_platform = function
 	| "cross" -> Cross
 	| "cross" -> Cross
@@ -96,7 +115,7 @@ let parse_platform = function
 	| "python" -> Python
 	| "python" -> Python
 	| "hl" -> Hl
 	| "hl" -> Hl
 	| "eval" -> Eval
 	| "eval" -> Eval
-	| p -> raise (failwith ("invalid platform " ^ p))
+	| p -> CustomTarget p
 
 
 let platform_list_help = function
 let platform_list_help = function
 	| [] -> ""
 	| [] -> ""
@@ -191,16 +210,36 @@ type compiler_message = {
 	cm_message : string;
 	cm_message : string;
 	cm_pos : pos;
 	cm_pos : pos;
 	cm_depth : int;
 	cm_depth : int;
+	cm_from_macro : bool;
 	cm_kind : MessageKind.t;
 	cm_kind : MessageKind.t;
 	cm_severity : MessageSeverity.t;
 	cm_severity : MessageSeverity.t;
 }
 }
 
 
-let make_compiler_message msg p depth kind sev = {
-		cm_message = msg;
-		cm_pos = p;
-		cm_depth = depth;
-		cm_kind = kind;
-		cm_severity = sev;
+let make_compiler_message ?(from_macro = false) msg p depth kind sev = {
+	cm_message = msg;
+	cm_pos = p;
+	cm_depth = depth;
+	cm_from_macro = from_macro;
+	cm_kind = kind;
+	cm_severity = sev;
+}
+
+type diagnostic = {
+	diag_message : string;
+	diag_code : string option;
+	diag_pos : pos;
+	diag_kind : MessageKind.t;
+	diag_severity : MessageSeverity.t;
+	diag_depth : int;
+}
+
+let make_diagnostic ?(depth = 0) ?(code = None) message pos kind sev = {
+	diag_message = message;
+	diag_pos = pos;
+	diag_code = code;
+	diag_kind = kind;
+	diag_severity = sev;
+	diag_depth = depth;
 }
 }
 
 
 let i32_31 = Int32.of_int 31
 let i32_31 = Int32.of_int 31

+ 3 - 5
src/core/inheritDoc.ml

@@ -1,14 +1,12 @@
-open Globals
 open Ast
 open Ast
 open Type
 open Type
-open Typecore
 
 
 let expr_to_target e =
 let expr_to_target e =
 	let rec loop (e,p) =
 	let rec loop (e,p) =
 		match e with
 		match e with
 		| EConst (Ident s) when s <> "" -> [s]
 		| EConst (Ident s) when s <> "" -> [s]
 		| EField (e,s,_) -> s :: loop e
 		| EField (e,s,_) -> s :: loop e
-		| _ -> Error.typing_error "Invalid target expression for @:inheritDoc" p
+		| _ -> Error.raise_typing_error "Invalid target expression for @:inheritDoc" p
 	in
 	in
 	match loop e with
 	match loop e with
 	| sub_name :: type_name :: pack when not (is_lower_ident type_name) ->
 	| sub_name :: type_name :: pack when not (is_lower_ident type_name) ->
@@ -16,7 +14,7 @@ let expr_to_target e =
 	| type_name :: pack ->
 	| type_name :: pack ->
 		(List.rev pack, type_name), None
 		(List.rev pack, type_name), None
 	| [] ->
 	| [] ->
-		Error.typing_error "Invalid target path for @:inheritDoc" (snd e)
+		Error.raise_typing_error "Invalid target path for @:inheritDoc" (snd e)
 
 
 let rec get_constructor c =
 let rec get_constructor c =
 	match c.cl_constructor, c.cl_super with
 	match c.cl_constructor, c.cl_super with
@@ -194,7 +192,7 @@ and get_target_doc ctx e_target =
 		with Not_found ->
 		with Not_found ->
 			None
 			None
 	in
 	in
-	let rec resolve_type_t t =
+	let resolve_type_t t =
 		match follow t with
 		match follow t with
 		| TInst (c, _) ->
 		| TInst (c, _) ->
 			build_class_doc ctx c;
 			build_class_doc ctx c;

+ 8 - 6
src/core/json/genjson.ml

@@ -236,7 +236,7 @@ and generate_anon_status ctx status =
 		| Closed -> "AClosed",None
 		| Closed -> "AClosed",None
 		| Const -> "AConst",None
 		| Const -> "AConst",None
 		| Extend tl -> "AExtend", Some (generate_types ctx tl)
 		| Extend tl -> "AExtend", Some (generate_types ctx tl)
-		| Statics c -> "AClassStatics",Some (class_ref ctx c)
+		| ClassStatics c -> "AClassStatics",Some (class_ref ctx c)
 		| EnumStatics en -> "AEnumStatics",Some (enum_ref ctx en)
 		| EnumStatics en -> "AEnumStatics",Some (enum_ref ctx en)
 		| AbstractStatics a -> "AAbstractStatics", Some (abstract_ref ctx a)
 		| AbstractStatics a -> "AAbstractStatics", Some (abstract_ref ctx a)
 	in
 	in
@@ -707,7 +707,7 @@ let generate_module_type ctx mt =
 
 
 (* module *)
 (* module *)
 
 
-let generate_module cc m =
+let generate_module cs cc m =
 	jobject [
 	jobject [
 		"id",jint m.m_id;
 		"id",jint m.m_id;
 		"path",generate_module_path m.m_path;
 		"path",generate_module_path m.m_path;
@@ -718,10 +718,12 @@ let generate_module cc m =
 			| MSGood -> "Good"
 			| MSGood -> "Good"
 			| MSBad reason -> Printer.s_module_skip_reason reason
 			| MSBad reason -> Printer.s_module_skip_reason reason
 			| MSUnknown -> "Unknown");
 			| MSUnknown -> "Unknown");
-		"dependencies",jarray (PMap.fold (fun m acc -> (jobject [
-			"path",jstring (s_type_path m.m_path);
-			"sign",jstring (Digest.to_hex m.m_extra.m_sign);
-		]) :: acc) m.m_extra.m_deps []);
+		"dependencies",jarray (PMap.fold (fun (sign,mpath) acc ->
+			(jobject [
+				"path",jstring (s_type_path mpath);
+				"sign",jstring (Digest.to_hex ((cs#get_context sign)#find_module mpath).m_extra.m_sign);
+			]) :: acc
+		) m.m_extra.m_deps []);
 		"dependents",jarray (List.map (fun m -> (jobject [
 		"dependents",jarray (List.map (fun m -> (jobject [
 			"path",jstring (s_type_path m.m_path);
 			"path",jstring (s_type_path m.m_path);
 			"sign",jstring (Digest.to_hex m.m_extra.m_sign);
 			"sign",jstring (Digest.to_hex m.m_extra.m_sign);

+ 6 - 0
src/core/meta.ml

@@ -120,3 +120,9 @@ let get_user_documentation_list user_metas =
 let copy_from_to m src dst =
 let copy_from_to m src dst =
 	try (get m src) :: dst
 	try (get m src) :: dst
 	with Not_found -> dst
 	with Not_found -> dst
+
+let maybe_get_pos m ml = try
+		let (_,_,p) = get m ml in
+		Some p
+	with Not_found ->
+		None

+ 2 - 2
src/core/path.ml

@@ -223,7 +223,7 @@ end = struct
 
 
 	let create =
 	let create =
 		if Globals.is_windows then
 		if Globals.is_windows then
-			(fun f -> String.lowercase (get_full_path f))
+			(fun f -> ExtString.String.lowercase (get_full_path f))
 		else
 		else
 			get_full_path
 			get_full_path
 
 
@@ -378,7 +378,7 @@ let full_dot_path pack mname tname =
 
 
 let file_extension file =
 let file_extension file =
 	match List.rev (ExtString.String.nsplit file ".") with
 	match List.rev (ExtString.String.nsplit file ".") with
-	| e :: _ -> String.lowercase e
+	| e :: _ -> ExtString.String.lowercase e
 	| [] -> ""
 	| [] -> ""
 
 
 module FilePath = struct
 module FilePath = struct

+ 12 - 3
src/core/tFunctions.ml

@@ -172,6 +172,13 @@ let module_extra file sign time kind policy =
 		m_check_policy = policy;
 		m_check_policy = policy;
 	}
 	}
 
 
+let mk_class_field_ref (c : tclass) (cf : tclass_field) (kind : class_field_ref_kind) (is_macro : bool) = {
+	cfr_sign = c.cl_module.m_extra.m_sign;
+	cfr_path = c.cl_path;
+	cfr_field = cf.cf_name;
+	cfr_kind = kind;
+	cfr_is_macro = is_macro;
+}
 
 
 let mk_field name ?(public = true) ?(static = false) t p name_pos = {
 let mk_field name ?(public = true) ?(static = false) t p name_pos = {
 	cf_name = name;
 	cf_name = name;
@@ -233,8 +240,8 @@ let null_abstract = {
 }
 }
 
 
 let add_dependency ?(skip_postprocess=false) m mdep =
 let add_dependency ?(skip_postprocess=false) m mdep =
-	if m != null_module && m != mdep then begin
-		m.m_extra.m_deps <- PMap.add mdep.m_id mdep m.m_extra.m_deps;
+	if m != null_module && (m.m_path != mdep.m_path || m.m_extra.m_sign != mdep.m_extra.m_sign) then begin
+		m.m_extra.m_deps <- PMap.add mdep.m_id (mdep.m_extra.m_sign, mdep.m_path) m.m_extra.m_deps;
 		(* In case the module is cached, we'll have to run post-processing on it again (issue #10635) *)
 		(* In case the module is cached, we'll have to run post-processing on it again (issue #10635) *)
 		if not skip_postprocess then m.m_extra.m_processed <- 0
 		if not skip_postprocess then m.m_extra.m_processed <- 0
 	end
 	end
@@ -250,6 +257,8 @@ let t_infos t : tinfos =
 
 
 let t_path t = (t_infos t).mt_path
 let t_path t = (t_infos t).mt_path
 
 
+let t_name t = snd (t_path t)
+
 let rec extends c csup =
 let rec extends c csup =
 	if c == csup || List.exists (fun (i,_) -> extends i csup) c.cl_implements then
 	if c == csup || List.exists (fun (i,_) -> extends i csup) c.cl_implements then
 		true
 		true
@@ -781,7 +790,7 @@ let quick_field t n =
 		| EnumStatics e ->
 		| EnumStatics e ->
 			let ef = PMap.find n e.e_constrs in
 			let ef = PMap.find n e.e_constrs in
 			FEnum(e,ef)
 			FEnum(e,ef)
-		| Statics c ->
+		| ClassStatics c ->
 			FStatic (c,PMap.find n c.cl_statics)
 			FStatic (c,PMap.find n c.cl_statics)
 		| AbstractStatics a ->
 		| AbstractStatics a ->
 			begin match a.a_impl with
 			begin match a.a_impl with

+ 4 - 4
src/core/tOther.ml

@@ -42,7 +42,7 @@ module TExprToExpr = struct
 				) args, (convert_type' ret))
 				) args, (convert_type' ret))
 		| TAnon a ->
 		| TAnon a ->
 			begin match !(a.a_status) with
 			begin match !(a.a_status) with
-			| Statics c -> tpath ([],"Class") ([],"Class") [TPType (tpath c.cl_path c.cl_path [],null_pos)]
+			| ClassStatics c -> tpath ([],"Class") ([],"Class") [TPType (tpath c.cl_path c.cl_path [],null_pos)]
 			| EnumStatics e -> tpath ([],"Enum") ([],"Enum") [TPType (tpath e.e_path e.e_path [],null_pos)]
 			| EnumStatics e -> tpath ([],"Enum") ([],"Enum") [TPType (tpath e.e_path e.e_path [],null_pos)]
 			| _ ->
 			| _ ->
 				CTAnonymous (PMap.foldi (fun _ f acc ->
 				CTAnonymous (PMap.foldi (fun _ f acc ->
@@ -149,8 +149,8 @@ module TExprToExpr = struct
 			EFor (ein,convert_expr e)
 			EFor (ein,convert_expr e)
 		| TIf (e,e1,e2) -> EIf (convert_expr e,convert_expr e1,eopt e2)
 		| TIf (e,e1,e2) -> EIf (convert_expr e,convert_expr e1,eopt e2)
 		| TWhile (e1,e2,flag) -> EWhile (convert_expr e1, convert_expr e2, flag)
 		| TWhile (e1,e2,flag) -> EWhile (convert_expr e1, convert_expr e2, flag)
-		| TSwitch (e,cases,def) ->
-			let cases = List.map (fun (vl,e) ->
+		| TSwitch {switch_subject = e;switch_cases = cases;switch_default = def} ->
+			let cases = List.map (fun {case_patterns = vl;case_expr = e} ->
 				List.map convert_expr vl,None,(match e.eexpr with TBlock [] -> None | _ -> Some (convert_expr e)),e.epos
 				List.map convert_expr vl,None,(match e.eexpr with TBlock [] -> None | _ -> Some (convert_expr e)),e.epos
 			) cases in
 			) cases in
 			let def = match eopt def with None -> None | Some (EBlock [],_) -> Some (None,null_pos) | Some e -> Some (Some e,pos e) in
 			let def = match eopt def with None -> None | Some (EBlock [],_) -> Some (None,null_pos) | Some e -> Some (Some e,pos e) in
@@ -265,7 +265,7 @@ let no_meta = []
 
 
 let class_module_type c =
 let class_module_type c =
 	let path = ([],"Class<" ^ (s_type_path c.cl_path) ^ ">") in
 	let path = ([],"Class<" ^ (s_type_path c.cl_path) ^ ">") in
-	let t = mk_anon ~fields:c.cl_statics (ref (Statics c)) in
+	let t = mk_anon ~fields:c.cl_statics (ref (ClassStatics c)) in
 	{ (mk_typedef c.cl_module path c.cl_pos null_pos t) with t_private = true}
 	{ (mk_typedef c.cl_module path c.cl_pos null_pos t) with t_private = true}
 
 
 let enum_module_type m path p  =
 let enum_module_type m path p  =

+ 34 - 96
src/core/tPrinting.ml

@@ -58,7 +58,7 @@ let rec s_type ctx t =
 		(match c.cl_kind with
 		(match c.cl_kind with
 		| KExpr e -> Ast.Printer.s_expr e
 		| KExpr e -> Ast.Printer.s_expr e
 		| _ -> s_type_path c.cl_path ^ s_type_params ctx tl)
 		| _ -> s_type_path c.cl_path ^ s_type_params ctx tl)
-	| TType ({ t_type = TAnon { a_status = { contents = Statics { cl_kind = KAbstractImpl a }}}}, _) ->
+	| TType ({ t_type = TAnon { a_status = { contents = ClassStatics { cl_kind = KAbstractImpl a }}}}, _) ->
 		"Abstract<" ^ (s_type_path a.a_path) ^ ">"
 		"Abstract<" ^ (s_type_path a.a_path) ^ ">"
 	| TType (t,tl) ->
 	| TType (t,tl) ->
 		s_type_path t.t_path ^ s_type_params ctx tl
 		s_type_path t.t_path ^ s_type_params ctx tl
@@ -80,7 +80,7 @@ let rec s_type ctx t =
 	| TAnon a ->
 	| TAnon a ->
 		begin
 		begin
 			match !(a.a_status) with
 			match !(a.a_status) with
-			| Statics c -> Printf.sprintf "{ Statics %s }" (s_type_path c.cl_path)
+			| ClassStatics c -> Printf.sprintf "{ ClassStatics %s }" (s_type_path c.cl_path)
 			| EnumStatics e -> Printf.sprintf "{ EnumStatics %s }" (s_type_path e.e_path)
 			| EnumStatics e -> Printf.sprintf "{ EnumStatics %s }" (s_type_path e.e_path)
 			| AbstractStatics a -> Printf.sprintf "{ AbstractStatics %s }" (s_type_path a.a_path)
 			| AbstractStatics a -> Printf.sprintf "{ AbstractStatics %s }" (s_type_path a.a_path)
 			| _ ->
 			| _ ->
@@ -161,7 +161,7 @@ let s_expr_kind e =
 	| TFor (_,_,_) -> "For"
 	| TFor (_,_,_) -> "For"
 	| TIf (_,_,_) -> "If"
 	| TIf (_,_,_) -> "If"
 	| TWhile (_,_,_) -> "While"
 	| TWhile (_,_,_) -> "While"
-	| TSwitch (_,_,_) -> "Switch"
+	| TSwitch _ -> "Switch"
 	| TTry (_,_) -> "Try"
 	| TTry (_,_) -> "Try"
 	| TReturn _ -> "Return"
 	| TReturn _ -> "Return"
 	| TBreak -> "Break"
 	| TBreak -> "Break"
@@ -188,81 +188,6 @@ let s_field_access s_type fa = match fa with
 	| FEnum (en,f) -> "enum(" ^ s_type_path en.e_path ^ "." ^ f.ef_name ^ ")"
 	| FEnum (en,f) -> "enum(" ^ s_type_path en.e_path ^ "." ^ f.ef_name ^ ")"
 	| FDynamic f -> "dynamic(" ^ f ^ ")"
 	| FDynamic f -> "dynamic(" ^ f ^ ")"
 
 
-let rec s_expr s_type e =
-	let sprintf = Printf.sprintf in
-	let slist f l = String.concat "," (List.map f l) in
-	let loop = s_expr s_type in
-	let s_var v = v.v_name ^ ":" ^ string_of_int v.v_id ^ if has_var_flag v VCaptured then "[c]" else "" in
-	let str = (match e.eexpr with
-	| TConst c ->
-		"Const " ^ s_const c
-	| TLocal v ->
-		"Local " ^ s_var v
-	| TArray (e1,e2) ->
-		sprintf "%s[%s]" (loop e1) (loop e2)
-	| TBinop (op,e1,e2) ->
-		sprintf "(%s %s %s)" (loop e1) (s_binop op) (loop e2)
-	| TEnumIndex e1 ->
-		sprintf "EnumIndex %s" (loop e1)
-	| TEnumParameter (e1,_,i) ->
-		sprintf "%s[%i]" (loop e1) i
-	| TField (e,f) ->
-		let fstr = s_field_access s_type f in
-		sprintf "%s.%s" (loop e) fstr
-	| TTypeExpr m ->
-		sprintf "TypeExpr %s" (s_type_path (t_path m))
-	| TParenthesis e ->
-		sprintf "Parenthesis %s" (loop e)
-	| TObjectDecl fl ->
-		sprintf "ObjectDecl {%s}" (slist (fun ((f,_,qs),e) -> sprintf "%s : %s" (s_object_key_name f qs) (loop e)) fl)
-	| TArrayDecl el ->
-		sprintf "ArrayDecl [%s]" (slist loop el)
-	| TCall (e,el) ->
-		sprintf "Call %s(%s)" (loop e) (slist loop el)
-	| TNew (c,pl,el) ->
-		sprintf "New %s%s(%s)" (s_type_path c.cl_path) (match pl with [] -> "" | l -> sprintf "<%s>" (slist s_type l)) (slist loop el)
-	| TUnop (op,f,e) ->
-		(match f with
-		| Prefix -> sprintf "(%s %s)" (s_unop op) (loop e)
-		| Postfix -> sprintf "(%s %s)" (loop e) (s_unop op))
-	| TFunction f ->
-		let args = slist (fun (v,o) -> sprintf "%s : %s%s" (s_var v) (s_type v.v_type) (match o with None -> "" | Some c -> " = " ^ loop c)) f.tf_args in
-		sprintf "Function(%s) : %s = %s" args (s_type f.tf_type) (loop f.tf_expr)
-	| TVar (v,eo) ->
-		sprintf "Vars %s" (sprintf "%s : %s%s" (s_var v) (s_type v.v_type) (match eo with None -> "" | Some e -> " = " ^ loop e))
-	| TBlock el ->
-		sprintf "Block {\n%s}" (String.concat "" (List.map (fun e -> sprintf "%s;\n" (loop e)) el))
-	| TFor (v,econd,e) ->
-		sprintf "For (%s : %s in %s,%s)" (s_var v) (s_type v.v_type) (loop econd) (loop e)
-	| TIf (e,e1,e2) ->
-		sprintf "If (%s,%s%s)" (loop e) (loop e1) (match e2 with None -> "" | Some e -> "," ^ loop e)
-	| TWhile (econd,e,flag) ->
-		(match flag with
-		| NormalWhile -> sprintf "While (%s,%s)" (loop econd) (loop e)
-		| DoWhile -> sprintf "DoWhile (%s,%s)" (loop e) (loop econd))
-	| TSwitch (e,cases,def) ->
-		sprintf "Switch (%s,(%s)%s)" (loop e) (slist (fun (cl,e) -> sprintf "case %s: %s" (slist loop cl) (loop e)) cases) (match def with None -> "" | Some e -> "," ^ loop e)
-	| TTry (e,cl) ->
-		sprintf "Try %s(%s) " (loop e) (slist (fun (v,e) -> sprintf "catch( %s : %s ) %s" (s_var v) (s_type v.v_type) (loop e)) cl)
-	| TReturn None ->
-		"Return"
-	| TReturn (Some e) ->
-		sprintf "Return %s" (loop e)
-	| TBreak ->
-		"Break"
-	| TContinue ->
-		"Continue"
-	| TThrow e ->
-		"Throw " ^ (loop e)
-	| TCast (e,t) ->
-		sprintf "Cast %s%s" (match t with None -> "" | Some t -> s_type_path (t_path t) ^ ": ") (loop e)
-	| TMeta ((n,el,_),e) ->
-		sprintf "@%s%s %s" (Meta.to_string n) (match el with [] -> "" | _ -> "(" ^ (String.concat ", " (List.map Ast.Printer.s_expr el)) ^ ")") (loop e)
-	| TIdent s ->
-		"Ident " ^ s
-	) in
-	sprintf "(%s : %s)" str (s_type e.etype)
-
 let rec s_expr_pretty print_var_ids tabs top_level s_type e =
 let rec s_expr_pretty print_var_ids tabs top_level s_type e =
 	let sprintf = Printf.sprintf in
 	let sprintf = Printf.sprintf in
 	let loop = s_expr_pretty print_var_ids tabs false s_type in
 	let loop = s_expr_pretty print_var_ids tabs false s_type in
@@ -307,9 +232,12 @@ let rec s_expr_pretty print_var_ids tabs top_level s_type e =
 		(match flag with
 		(match flag with
 		| NormalWhile -> sprintf "while (%s) %s" (loop econd) (loop e)
 		| NormalWhile -> sprintf "while (%s) %s" (loop econd) (loop e)
 		| DoWhile -> sprintf "do (%s) while(%s)" (loop e) (loop econd))
 		| DoWhile -> sprintf "do (%s) while(%s)" (loop e) (loop econd))
-	| TSwitch (e,cases,def) ->
+	| TSwitch switch ->
 		let ntabs = tabs ^ "\t" in
 		let ntabs = tabs ^ "\t" in
-		let s = sprintf "switch (%s) {\n%s%s" (loop e) (slist "" (fun (cl,e) -> sprintf "%scase %s: %s;\n" ntabs (clist loop cl) (s_expr_pretty print_var_ids ntabs top_level s_type e)) cases) (match def with None -> "" | Some e -> ntabs ^ "default: " ^ (s_expr_pretty print_var_ids ntabs top_level s_type e) ^ "\n") in
+		let s = sprintf "switch (%s) {\n%s%s"
+			(loop switch.switch_subject)
+			(slist "" (fun case -> sprintf "%scase %s: %s;\n" ntabs (clist loop case.case_patterns) (s_expr_pretty print_var_ids ntabs top_level s_type case.case_expr)) switch.switch_cases)
+			(match switch.switch_default with None -> "" | Some e -> ntabs ^ "default: " ^ (s_expr_pretty print_var_ids ntabs top_level s_type e) ^ "\n") in
 		s ^ tabs ^ "}"
 		s ^ tabs ^ "}"
 	| TTry (e,cl) ->
 	| TTry (e,cl) ->
 		sprintf "try %s%s" (loop e) (clist (fun (v,e) -> sprintf " catch (%s:%s) %s" (local v) (s_type v.v_type) (loop e)) cl)
 		sprintf "try %s%s" (loop e) (clist (fun (v,e) -> sprintf " catch (%s:%s) %s" (local v) (s_type v.v_type) (loop e)) cl)
@@ -332,6 +260,12 @@ let rec s_expr_pretty print_var_ids tabs top_level s_type e =
 	| TIdent s ->
 	| TIdent s ->
 		s
 		s
 
 
+let s_flags flags all_flags =
+	let _,l = List.fold_left (fun (i,acc) name ->
+		if has_flag flags i then (i + 1,name :: acc) else (i + 1,acc)
+	) (0,[]) all_flags in
+	String.concat " " l
+
 let rec s_expr_ast print_var_ids tabs s_type e =
 let rec s_expr_ast print_var_ids tabs s_type e =
 	let sprintf = Printf.sprintf in
 	let sprintf = Printf.sprintf in
 	let loop ?(extra_tabs="") = s_expr_ast print_var_ids (tabs ^ "\t" ^ extra_tabs) s_type in
 	let loop ?(extra_tabs="") = s_expr_ast print_var_ids (tabs ^ "\t" ^ extra_tabs) s_type in
@@ -352,7 +286,12 @@ let rec s_expr_ast print_var_ids tabs s_type e =
 	let var_id v = if print_var_ids then v.v_id else 0 in
 	let var_id v = if print_var_ids then v.v_id else 0 in
 	let const c t = tag "Const" ~t [s_const c] in
 	let const c t = tag "Const" ~t [s_const c] in
 	let local v t = sprintf "[Local %s(%i):%s%s]" v.v_name (var_id v) (s_type v.v_type) (match t with None -> "" | Some t -> ":" ^ (s_type t)) in
 	let local v t = sprintf "[Local %s(%i):%s%s]" v.v_name (var_id v) (s_type v.v_type) (match t with None -> "" | Some t -> ":" ^ (s_type t)) in
-	let var v sl = sprintf "[Var %s(%i):%s]%s" v.v_name (var_id v) (s_type v.v_type) (tag_args tabs sl) in
+	let var tag v sl =
+		let s_flags = match v.v_flags with
+			| 0 -> ""
+			| _ -> Printf.sprintf "(%s)" (s_flags v.v_flags flag_tvar_names)
+		in
+		sprintf "[%s %s<%i>%s:%s]%s" tag v.v_name (var_id v) s_flags (s_type v.v_type) (tag_args tabs sl) in
 	let module_type mt = sprintf "[TypeExpr %s:%s]" (s_type_path (t_path mt)) (s_type e.etype) in
 	let module_type mt = sprintf "[TypeExpr %s:%s]" (s_type_path (t_path mt)) (s_type e.etype) in
 	match e.eexpr with
 	match e.eexpr with
 	| TConst c -> const c (Some e.etype)
 	| TConst c -> const c (Some e.etype)
@@ -380,10 +319,10 @@ let rec s_expr_ast print_var_ids tabs s_type e =
 	| TNew (c,tl,el) -> tag "New" ((s_type (TInst(c,tl))) :: (List.map loop el))
 	| TNew (c,tl,el) -> tag "New" ((s_type (TInst(c,tl))) :: (List.map loop el))
 	| TFunction f ->
 	| TFunction f ->
 		let arg (v,cto) =
 		let arg (v,cto) =
-			tag "Arg" ~t:(Some v.v_type) ~extra_tabs:"\t" (match cto with None -> [local v None] | Some ct -> [local v None;loop ct])
+			var "Arg" v (match cto with None -> [] | Some e -> [loop e])
 		in
 		in
 		tag "Function" ((List.map arg f.tf_args) @ [loop f.tf_expr])
 		tag "Function" ((List.map arg f.tf_args) @ [loop f.tf_expr])
-	| TVar (v,eo) -> var v (match eo with None -> [] | Some e -> [loop e])
+	| TVar (v,eo) -> var "Var" v (match eo with None -> [] | Some e -> [loop e])
 	| TBlock el -> tag "Block" (List.map loop el)
 	| TBlock el -> tag "Block" (List.map loop el)
 	| TIf (e,e1,e2) -> tag "If" (loop e :: (Printf.sprintf "[Then:%s] %s" (s_type e1.etype) (loop e1)) :: (match e2 with None -> [] | Some e -> [Printf.sprintf "[Else:%s] %s" (s_type e.etype) (loop e)]))
 	| TIf (e,e1,e2) -> tag "If" (loop e :: (Printf.sprintf "[Then:%s] %s" (s_type e1.etype) (loop e1)) :: (match e2 with None -> [] | Some e -> [Printf.sprintf "[Else:%s] %s" (s_type e.etype) (loop e)]))
 	| TCast (e1,None) -> tag "Cast" [loop e1]
 	| TCast (e1,None) -> tag "Cast" [loop e1]
@@ -401,15 +340,15 @@ let rec s_expr_ast print_var_ids tabs s_type e =
 			sprintf "Catch %s%s" (local v None) (tag_args (tabs ^ "\t") [loop ~extra_tabs:"\t" e]);
 			sprintf "Catch %s%s" (local v None) (tag_args (tabs ^ "\t") [loop ~extra_tabs:"\t" e]);
 		) catches in
 		) catches in
 		tag "Try" ((loop e1) :: sl)
 		tag "Try" ((loop e1) :: sl)
-	| TSwitch (e1,cases,eo) ->
-		let sl = List.map (fun (el,e) ->
+	| TSwitch switch ->
+		let sl = List.map (fun {case_patterns = el;case_expr = e} ->
 			tag "Case" ~t:(Some e.etype) ~extra_tabs:"\t" ((List.map loop el) @ [loop ~extra_tabs:"\t" e])
 			tag "Case" ~t:(Some e.etype) ~extra_tabs:"\t" ((List.map loop el) @ [loop ~extra_tabs:"\t" e])
-		) cases in
-		let sl = match eo with
+		) switch.switch_cases in
+		let sl = match switch.switch_default with
 			| None -> sl
 			| None -> sl
 			| Some e -> sl @ [tag "Default" ~t:(Some e.etype) ~extra_tabs:"\t" [loop ~extra_tabs:"\t" e]]
 			| Some e -> sl @ [tag "Default" ~t:(Some e.etype) ~extra_tabs:"\t" [loop ~extra_tabs:"\t" e]]
 		in
 		in
-		tag "Switch" ((loop e1) :: sl)
+		tag "Switch" ((loop switch.switch_subject) :: sl)
 	| TMeta ((m,el,_),e1) ->
 	| TMeta ((m,el,_),e1) ->
 		let s = Meta.to_string m in
 		let s = Meta.to_string m in
 		let s = match el with
 		let s = match el with
@@ -450,6 +389,11 @@ let s_class_kind = function
 	| KModuleFields m ->
 	| KModuleFields m ->
 		Printf.sprintf "KModuleFields %s" (s_type_path m.m_path)
 		Printf.sprintf "KModuleFields %s" (s_type_path m.m_path)
 
 
+let s_class_field_ref_kind = function
+	| CfrStatic -> "CfrStatic"
+	| CfrMember -> "CfrMember"
+	| CfrConstructor -> "CfrConstructor"
+
 module Printer = struct
 module Printer = struct
 
 
 	let s_type t =
 	let s_type t =
@@ -506,12 +450,6 @@ module Printer = struct
 	let s_type_params tl =
 	let s_type_params tl =
 		s_list ", " s_type_param tl
 		s_list ", " s_type_param tl
 
 
-	let s_flags flags all_flags =
-		let _,l = List.fold_left (fun (i,acc) name ->
-			if has_flag flags i then (i + 1,name :: acc) else (i + 1,acc)
-		) (0,[]) all_flags in
-		String.concat " " l
-
 	let s_tclass_field_flags flags =
 	let s_tclass_field_flags flags =
 		s_flags flags flag_tclass_field_names
 		s_flags flags flag_tclass_field_names
 
 
@@ -667,12 +605,12 @@ module Printer = struct
 	let s_module_def_extra tabs me =
 	let s_module_def_extra tabs me =
 		s_record_fields tabs [
 		s_record_fields tabs [
 			"m_file",Path.UniqueKey.lazy_path me.m_file;
 			"m_file",Path.UniqueKey.lazy_path me.m_file;
-			"m_sign",me.m_sign;
+			"m_sign",(Digest.to_hex me.m_sign);
 			"m_time",string_of_float me.m_time;
 			"m_time",string_of_float me.m_time;
 			"m_cache_state",s_module_cache_state me.m_cache_state;
 			"m_cache_state",s_module_cache_state me.m_cache_state;
 			"m_added",string_of_int me.m_added;
 			"m_added",string_of_int me.m_added;
 			"m_checked",string_of_int me.m_checked;
 			"m_checked",string_of_int me.m_checked;
-			"m_deps",s_pmap string_of_int (fun m -> snd m.m_path) me.m_deps;
+			"m_deps",s_pmap string_of_int (fun (_,m) -> snd m) me.m_deps;
 			"m_processed",string_of_int me.m_processed;
 			"m_processed",string_of_int me.m_processed;
 			"m_kind",s_module_kind me.m_kind;
 			"m_kind",s_module_kind me.m_kind;
 			"m_binded_res",""; (* TODO *)
 			"m_binded_res",""; (* TODO *)

+ 33 - 4
src/core/tType.ml

@@ -149,7 +149,7 @@ and anon_status =
 	| Closed
 	| Closed
 	| Const
 	| Const
 	| Extend of t list
 	| Extend of t list
-	| Statics of tclass
+	| ClassStatics of tclass
 	| EnumStatics of tenum
 	| EnumStatics of tenum
 	| AbstractStatics of tabstract
 	| AbstractStatics of tabstract
 
 
@@ -177,7 +177,7 @@ and texpr_expr =
 	| TFor of tvar * texpr * texpr
 	| TFor of tvar * texpr * texpr
 	| TIf of texpr * texpr * texpr option
 	| TIf of texpr * texpr * texpr option
 	| TWhile of texpr * texpr * Ast.while_flag
 	| TWhile of texpr * texpr * Ast.while_flag
-	| TSwitch of texpr * (texpr list * texpr) list * texpr option
+	| TSwitch of tswitch
 	| TTry of texpr * (tvar * texpr) list
 	| TTry of texpr * (tvar * texpr) list
 	| TReturn of texpr option
 	| TReturn of texpr option
 	| TBreak
 	| TBreak
@@ -189,6 +189,18 @@ and texpr_expr =
 	| TEnumIndex of texpr
 	| TEnumIndex of texpr
 	| TIdent of string
 	| TIdent of string
 
 
+and tswitch = {
+	switch_subject : texpr;
+	switch_cases : switch_case list;
+	switch_default: texpr option;
+	switch_exhaustive : bool;
+}
+
+and switch_case = {
+	case_patterns : texpr list;
+	case_expr : texpr;
+}
+
 and tfield_access =
 and tfield_access =
 	| FInstance of tclass * tparams * tclass_field
 	| FInstance of tclass * tparams * tclass_field
 	| FStatic of tclass * tclass_field
 	| FStatic of tclass * tclass_field
@@ -378,13 +390,26 @@ and module_def_extra = {
 	mutable m_added : int;
 	mutable m_added : int;
 	mutable m_checked : int;
 	mutable m_checked : int;
 	mutable m_processed : int;
 	mutable m_processed : int;
-	mutable m_deps : (int,module_def) PMap.t;
+	mutable m_deps : (int,(string (* sign *) * path)) PMap.t;
 	mutable m_kind : module_kind;
 	mutable m_kind : module_kind;
 	mutable m_binded_res : (string, string) PMap.t;
 	mutable m_binded_res : (string, string) PMap.t;
-	mutable m_if_feature : (string *(tclass * tclass_field * bool)) list;
+	mutable m_if_feature : (string * class_field_ref) list;
 	mutable m_features : (string,bool) Hashtbl.t;
 	mutable m_features : (string,bool) Hashtbl.t;
 }
 }
 
 
+and class_field_ref_kind =
+	| CfrStatic
+	| CfrMember
+	| CfrConstructor
+
+and class_field_ref = {
+	cfr_sign : string;
+	cfr_path : path;
+	cfr_field : string;
+	cfr_kind : class_field_ref_kind;
+	cfr_is_macro : bool;
+}
+
 and module_kind =
 and module_kind =
 	| MCode
 	| MCode
 	| MMacro
 	| MMacro
@@ -446,3 +471,7 @@ type flag_tvar =
 	| VAssigned
 	| VAssigned
 	| VCaught
 	| VCaught
 	| VStatic
 	| VStatic
+
+let flag_tvar_names = [
+	"VCaptured";"VFinal";"VUsed";"VAssigned";"VCaught";"VStatic"
+]

+ 9 - 9
src/core/tUnification.ml

@@ -166,7 +166,7 @@ module Monomorph = struct
 		| CMixed l ->
 		| CMixed l ->
 			List.iter (fun constr -> check_down_constraints constr t) l
 			List.iter (fun constr -> check_down_constraints constr t) l
 
 
-	let rec collect_up_constraints m =
+	let collect_up_constraints m =
 		let rec collect m acc =
 		let rec collect m acc =
 			List.fold_left (fun acc (t,name) ->
 			List.fold_left (fun acc (t,name) ->
 				match t with
 				match t with
@@ -286,7 +286,7 @@ let rec follow_and_close t = match follow t with
 	| t ->
 	| t ->
 		t
 		t
 
 
-let rec link e a b =
+let link e a b =
 	(* tell if setting a == b will create a type-loop *)
 	(* tell if setting a == b will create a type-loop *)
 	let rec loop t =
 	let rec loop t =
 		if t == a then
 		if t == a then
@@ -386,7 +386,7 @@ let rec shallow_eq a b =
 					loop (List.sort sort_compare fields1) (List.sort sort_compare fields2)
 					loop (List.sort sort_compare fields1) (List.sort sort_compare fields2)
 				in
 				in
 				(match !(a2.a_status), !(a1.a_status) with
 				(match !(a2.a_status), !(a1.a_status) with
-				| Statics c, Statics c2 -> c == c2
+				| ClassStatics c, ClassStatics c2 -> c == c2
 				| EnumStatics e, EnumStatics e2 -> e == e2
 				| EnumStatics e, EnumStatics e2 -> e == e2
 				| AbstractStatics a, AbstractStatics a2 -> a == a2
 				| AbstractStatics a, AbstractStatics a2 -> a == a2
 				| Extend tl1, Extend tl2 -> fields_eq() && List.for_all2 shallow_eq tl1 tl2
 				| Extend tl1, Extend tl2 -> fields_eq() && List.for_all2 shallow_eq tl1 tl2
@@ -560,7 +560,7 @@ let rec type_eq uctx a b =
 	| TAnon a1, TAnon a2 ->
 	| TAnon a1, TAnon a2 ->
 		(try
 		(try
 			(match !(a2.a_status) with
 			(match !(a2.a_status) with
-			| Statics c -> (match !(a1.a_status) with Statics c2 when c == c2 -> () | _ -> error [])
+			| ClassStatics c -> (match !(a1.a_status) with ClassStatics c2 when c == c2 -> () | _ -> error [])
 			| EnumStatics e -> (match !(a1.a_status) with EnumStatics e2 when e == e2 -> () | _ -> error [])
 			| EnumStatics e -> (match !(a1.a_status) with EnumStatics e2 when e == e2 -> () | _ -> error [])
 			| AbstractStatics a -> (match !(a1.a_status) with AbstractStatics a2 when a == a2 -> () | _ -> error [])
 			| AbstractStatics a -> (match !(a1.a_status) with AbstractStatics a2 when a == a2 -> () | _ -> error [])
 			| _ -> ()
 			| _ -> ()
@@ -801,7 +801,7 @@ let rec unify (uctx : unification_context) a b =
 				| _ -> ());
 				| _ -> ());
 			) an.a_fields;
 			) an.a_fields;
 			(match !(an.a_status) with
 			(match !(an.a_status) with
-			| Statics _ | EnumStatics _ | AbstractStatics _ -> error []
+			| ClassStatics _ | EnumStatics _ | AbstractStatics _ -> error []
 			| Closed | Extend _ | Const -> ())
 			| Closed | Extend _ | Const -> ())
 		with
 		with
 			Unify_error l -> error (cannot_unify a b :: l))
 			Unify_error l -> error (cannot_unify a b :: l))
@@ -809,7 +809,7 @@ let rec unify (uctx : unification_context) a b =
 		unify_anons uctx a b a1 a2
 		unify_anons uctx a b a1 a2
 	| TAnon an, TAbstract ({ a_path = [],"Class" },[pt]) ->
 	| TAnon an, TAbstract ({ a_path = [],"Class" },[pt]) ->
 		(match !(an.a_status) with
 		(match !(an.a_status) with
-		| Statics cl -> unify uctx (TInst (cl,List.map (fun _ -> mk_mono()) cl.cl_params)) pt
+		| ClassStatics cl -> unify uctx (TInst (cl,List.map (fun _ -> mk_mono()) cl.cl_params)) pt
 		| _ -> error [cannot_unify a b])
 		| _ -> error [cannot_unify a b])
 	| TAnon an, TAbstract ({ a_path = [],"Enum" },[pt]) ->
 	| TAnon an, TAbstract ({ a_path = [],"Enum" },[pt]) ->
 		(match !(an.a_status) with
 		(match !(an.a_status) with
@@ -867,7 +867,7 @@ let rec unify (uctx : unification_context) a b =
 		| TAnon an ->
 		| TAnon an ->
 			(try
 			(try
 				(match !(an.a_status) with
 				(match !(an.a_status) with
-				| Statics _ | EnumStatics _ -> error []
+				| ClassStatics _ | EnumStatics _ -> error []
 				| _ -> ());
 				| _ -> ());
 				PMap.iter (fun _ f ->
 				PMap.iter (fun _ f ->
 					try
 					try
@@ -910,7 +910,7 @@ and unify_anons uctx a b a1 a2 =
 				in
 				in
 				unify_with_access uctx f1 f1_type f2;
 				unify_with_access uctx f1 f1_type f2;
 				(match !(a1.a_status) with
 				(match !(a1.a_status) with
-				| Statics c when not (Meta.has Meta.MaybeUsed f1.cf_meta) -> f1.cf_meta <- (Meta.MaybeUsed,[],f1.cf_pos) :: f1.cf_meta
+				| ClassStatics c when not (Meta.has Meta.MaybeUsed f1.cf_meta) -> f1.cf_meta <- (Meta.MaybeUsed,[],f1.cf_pos) :: f1.cf_meta
 				| _ -> ());
 				| _ -> ());
 			with
 			with
 				Unify_error l -> error (invalid_field n :: l)
 				Unify_error l -> error (invalid_field n :: l)
@@ -923,7 +923,7 @@ and unify_anons uctx a b a1 a2 =
 					error [has_no_field a n];
 					error [has_no_field a n];
 		) a2.a_fields;
 		) a2.a_fields;
 		(match !(a2.a_status) with
 		(match !(a2.a_status) with
-		| Statics c -> (match !(a1.a_status) with Statics c2 when c == c2 -> () | _ -> error [])
+		| ClassStatics c -> (match !(a1.a_status) with ClassStatics c2 when c == c2 -> () | _ -> error [])
 		| EnumStatics e -> (match !(a1.a_status) with EnumStatics e2 when e == e2 -> () | _ -> error [])
 		| EnumStatics e -> (match !(a1.a_status) with EnumStatics e2 when e == e2 -> () | _ -> error [])
 		| AbstractStatics a -> (match !(a1.a_status) with AbstractStatics a2 when a == a2 -> () | _ -> error [])
 		| AbstractStatics a -> (match !(a1.a_status) with AbstractStatics a2 when a == a2 -> () | _ -> error [])
 		| Const | Extend _ | Closed -> ())
 		| Const | Extend _ | Closed -> ())

+ 79 - 65
src/core/texpr.ml

@@ -47,10 +47,10 @@ let iter f e =
 		f e;
 		f e;
 		f e1;
 		f e1;
 		(match e2 with None -> () | Some e -> f e)
 		(match e2 with None -> () | Some e -> f e)
-	| TSwitch (e,cases,def) ->
-		f e;
-		List.iter (fun (el,e2) -> List.iter f el; f e2) cases;
-		(match def with None -> () | Some e -> f e)
+	| TSwitch switch ->
+		f switch.switch_subject;
+		List.iter (fun case -> List.iter f case.case_patterns; f case.case_expr) switch.switch_cases;
+		(match switch.switch_default with None -> () | Some e -> f e)
 	| TTry (e,catches) ->
 	| TTry (e,catches) ->
 		f e;
 		f e;
 		List.iter (fun (_,e) -> f e) catches
 		List.iter (fun (_,e) -> f e) catches
@@ -83,10 +83,10 @@ let check_expr predicate e =
 			predicate fu.tf_expr
 			predicate fu.tf_expr
 		| TIf (e,e1,e2) ->
 		| TIf (e,e1,e2) ->
 			predicate e || predicate e1 || (match e2 with None -> false | Some e -> predicate e)
 			predicate e || predicate e1 || (match e2 with None -> false | Some e -> predicate e)
-		| TSwitch (e,cases,def) ->
-			predicate e
-			|| List.exists (fun (el,e2) -> List.exists predicate el || predicate e2) cases
-			|| (match def with None -> false | Some e -> predicate e)
+		| TSwitch switch ->
+			predicate switch.switch_subject
+			|| List.exists (fun case -> List.exists predicate case.case_patterns || predicate case.case_expr) switch.switch_cases
+			|| (match switch.switch_default with None -> false | Some e -> predicate e)
 		| TTry (e,catches) ->
 		| TTry (e,catches) ->
 			predicate e || List.exists (fun (_,e) -> predicate e) catches
 			predicate e || List.exists (fun (_,e) -> predicate e) catches
 
 
@@ -142,10 +142,14 @@ let map_expr f e =
 		let ec = f ec in
 		let ec = f ec in
 		let e1 = f e1 in
 		let e1 = f e1 in
 		{ e with eexpr = TIf (ec,e1,match e2 with None -> None | Some e -> Some (f e)) }
 		{ e with eexpr = TIf (ec,e1,match e2 with None -> None | Some e -> Some (f e)) }
-	| TSwitch (e1,cases,def) ->
-		let e1 = f e1 in
-		let cases = List.map (fun (el,e2) -> List.map f el, f e2) cases in
-		{ e with eexpr = TSwitch (e1, cases, match def with None -> None | Some e -> Some (f e)) }
+	| TSwitch switch ->
+		let e1 = f switch.switch_subject in
+		let cases = List.map (fun case -> {
+			case_patterns = List.map f case.case_patterns;
+			case_expr = f case.case_expr
+		}) switch.switch_cases in
+		let def = Option.map f switch.switch_default in
+		{ e with eexpr = TSwitch {switch with switch_subject = e1;switch_cases = cases;switch_default = def} }
 	| TTry (e1,catches) ->
 	| TTry (e1,catches) ->
 		let e1 = f e1 in
 		let e1 = f e1 in
 		{ e with eexpr = TTry (e1, List.map (fun (v,e) -> v, f e) catches) }
 		{ e with eexpr = TTry (e1, List.map (fun (v,e) -> v, f e) catches) }
@@ -228,7 +232,7 @@ let map_expr_type f ft fv e =
 	| TFunction fu ->
 	| TFunction fu ->
 		let fu = {
 		let fu = {
 			tf_expr = f fu.tf_expr;
 			tf_expr = f fu.tf_expr;
-			tf_args = List.map (fun (v,o) -> fv v, o) fu.tf_args;
+			tf_args = List.map (fun (v,o) -> fv v, (Option.map f o)) fu.tf_args;
 			tf_type = ft fu.tf_type;
 			tf_type = ft fu.tf_type;
 		} in
 		} in
 		{ e with eexpr = TFunction fu; etype = ft e.etype }
 		{ e with eexpr = TFunction fu; etype = ft e.etype }
@@ -236,10 +240,14 @@ let map_expr_type f ft fv e =
 		let ec = f ec in
 		let ec = f ec in
 		let e1 = f e1 in
 		let e1 = f e1 in
 		{ e with eexpr = TIf (ec,e1,match e2 with None -> None | Some e -> Some (f e)); etype = ft e.etype }
 		{ e with eexpr = TIf (ec,e1,match e2 with None -> None | Some e -> Some (f e)); etype = ft e.etype }
-	| TSwitch (e1,cases,def) ->
-		let e1 = f e1 in
-		let cases = List.map (fun (el,e2) -> List.map f el, f e2) cases in
-		{ e with eexpr = TSwitch (e1, cases, match def with None -> None | Some e -> Some (f e)); etype = ft e.etype }
+	| TSwitch switch ->
+		let e1 = f switch.switch_subject in
+		let cases = List.map (fun case -> {
+			case_patterns = List.map f case.case_patterns;
+			case_expr = f case.case_expr
+		}) switch.switch_cases in
+		let def = Option.map f switch.switch_default in
+		{ e with eexpr = TSwitch {switch with switch_subject = e1;switch_cases = cases;switch_default = def}; etype = ft e.etype }
 	| TTry (e1,catches) ->
 	| TTry (e1,catches) ->
 		let e1 = f e1 in
 		let e1 = f e1 in
 		{ e with eexpr = TTry (e1, List.map (fun (v,e) -> fv v, f e) catches); etype = ft e.etype }
 		{ e with eexpr = TTry (e1, List.map (fun (v,e) -> fv v, f e) catches); etype = ft e.etype }
@@ -284,10 +292,10 @@ let rec equal e1 e2 = match e1.eexpr,e2.eexpr with
 	| TIf(e1,ethen1,None),TIf(e2,ethen2,None) -> equal e1 e2 && equal ethen1 ethen2
 	| TIf(e1,ethen1,None),TIf(e2,ethen2,None) -> equal e1 e2 && equal ethen1 ethen2
 	| TIf(e1,ethen1,Some eelse1),TIf(e2,ethen2,Some eelse2) -> equal e1 e2 && equal ethen1 ethen2 && equal eelse1 eelse2
 	| TIf(e1,ethen1,Some eelse1),TIf(e2,ethen2,Some eelse2) -> equal e1 e2 && equal ethen1 ethen2 && equal eelse1 eelse2
 	| TWhile(e1,eb1,flag1),TWhile(e2,eb2,flag2) -> equal e1 e2 && equal eb2 eb2 && flag1 = flag2
 	| TWhile(e1,eb1,flag1),TWhile(e2,eb2,flag2) -> equal e1 e2 && equal eb2 eb2 && flag1 = flag2
-	| TSwitch(e1,cases1,eo1),TSwitch(e2,cases2,eo2) ->
-		equal e1 e2 &&
-		safe_for_all2 (fun (el1,e1) (el2,e2) -> safe_for_all2 equal el1 el2 && equal e1 e2) cases1 cases2 &&
-		(match eo1,eo2 with None,None -> true | Some e1,Some e2 -> equal e1 e2 | _ -> false)
+	| TSwitch switch1,TSwitch switch2 ->
+		equal switch1.switch_subject switch2.switch_subject &&
+		safe_for_all2 (fun case1 case2 -> safe_for_all2 equal case1.case_patterns case2.case_patterns && equal case1.case_expr case2.case_expr) switch1.switch_cases switch2.switch_cases &&
+		(match switch1.switch_default,switch2.switch_default with None,None -> true | Some e1,Some e2 -> equal e1 e2 | _ -> false)
 	| TTry(e1,catches1),TTry(e2,catches2) -> equal e1 e2 && safe_for_all2 (fun (v1,e1) (v2,e2) -> v1 == v2 && equal e1 e2) catches1 catches2
 	| TTry(e1,catches1),TTry(e2,catches2) -> equal e1 e2 && safe_for_all2 (fun (v1,e1) (v2,e2) -> v1 == v2 && equal e1 e2) catches1 catches2
 	| TReturn None,TReturn None -> true
 	| TReturn None,TReturn None -> true
 	| TReturn(Some e1),TReturn(Some e2) -> equal e1 e2
 	| TReturn(Some e1),TReturn(Some e2) -> equal e1 e2
@@ -299,7 +307,9 @@ let rec equal e1 e2 = match e1.eexpr,e2.eexpr with
 	| TEnumParameter(e1,ef1,i1),TEnumParameter(e2,ef2,i2) -> equal e1 e2 && ef1 == ef2 && i1 = i2
 	| TEnumParameter(e1,ef1,i1),TEnumParameter(e2,ef2,i2) -> equal e1 e2 && ef1 == ef2 && i1 = i2
 	| _ -> false
 	| _ -> false
 
 
-let duplicate_tvars e =
+let e_identity e = e
+
+let duplicate_tvars f_this e =
 	let vars = Hashtbl.create 0 in
 	let vars = Hashtbl.create 0 in
 	let copy_var v =
 	let copy_var v =
 		let v2 = alloc_var v.v_kind v.v_name v.v_type v.v_pos in
 		let v2 = alloc_var v.v_kind v.v_name v.v_type v.v_pos in
@@ -336,6 +346,8 @@ let duplicate_tvars e =
 				{e with eexpr = TLocal v2}
 				{e with eexpr = TLocal v2}
 			with _ ->
 			with _ ->
 				e)
 				e)
+		| TConst TThis ->
+			f_this e
 		| _ ->
 		| _ ->
 			map_expr build_expr e
 			map_expr build_expr e
 	in
 	in
@@ -434,15 +446,15 @@ let foldmap f acc e =
 		let acc,e1 = f acc e1 in
 		let acc,e1 = f acc e1 in
 		let acc,eo = foldmap_opt f acc eo in
 		let acc,eo = foldmap_opt f acc eo in
 		acc,{ e with eexpr = TIf (ec,e1,eo)}
 		acc,{ e with eexpr = TIf (ec,e1,eo)}
-	| TSwitch (e1,cases,def) ->
-		let acc,e1 = f acc e1 in
-		let acc,cases = List.fold_left (fun (acc,cases) (el,e2) ->
-			let acc,el = foldmap_list f acc el in
-			let acc,e2 = f acc e2 in
-			acc,((el,e2) :: cases)
-		) (acc,[]) cases in
-		let acc,def = foldmap_opt f acc def in
-		acc,{ e with eexpr = TSwitch (e1, cases, def) }
+	| TSwitch switch ->
+		let acc,e1 = f acc switch.switch_subject in
+		let acc,cases = List.fold_left (fun (acc,cases) case ->
+			let acc,el = foldmap_list f acc case.case_patterns in
+			let acc,e2 = f acc case.case_expr in
+			acc,({case_patterns = el;case_expr = e2} :: cases)
+		) (acc,[]) switch.switch_cases in
+		let acc,def = foldmap_opt f acc switch.switch_default in
+		acc,{ e with eexpr = TSwitch {switch with switch_subject = e1;switch_cases = cases;switch_default = def} }
 	| TTry (e1,catches) ->
 	| TTry (e1,catches) ->
 		let acc,e1 = f acc e1 in
 		let acc,e1 = f acc e1 in
 		let acc,catches = foldmap_pairs f acc catches in
 		let acc,catches = foldmap_pairs f acc catches in
@@ -461,22 +473,22 @@ let foldmap f acc e =
 (* Collection of functions that return expressions *)
 (* Collection of functions that return expressions *)
 module Builder = struct
 module Builder = struct
 	let make_static_this c p =
 	let make_static_this c p =
-		let ta = mk_anon ~fields:c.cl_statics (ref (Statics c)) in
+		let ta = mk_anon ~fields:c.cl_statics (ref (ClassStatics c)) in
 		mk (TTypeExpr (TClassDecl c)) ta p
 		mk (TTypeExpr (TClassDecl c)) ta p
 
 
 	let make_typeexpr mt pos =
 	let make_typeexpr mt pos =
 		let t =
 		let t =
 			match resolve_typedef mt with
 			match resolve_typedef mt with
-			| TClassDecl c -> mk_anon ~fields:c.cl_statics (ref (Statics c))
+			| TClassDecl c -> mk_anon ~fields:c.cl_statics (ref (ClassStatics c))
 			| TEnumDecl e -> mk_anon (ref (EnumStatics e))
 			| TEnumDecl e -> mk_anon (ref (EnumStatics e))
 			| TAbstractDecl a -> mk_anon (ref (AbstractStatics a))
 			| TAbstractDecl a -> mk_anon (ref (AbstractStatics a))
 			| _ -> die "" __LOC__
 			| _ -> die "" __LOC__
 		in
 		in
 		mk (TTypeExpr mt) t pos
 		mk (TTypeExpr mt) t pos
 
 
-	let make_static_field c cf p =
-		let e_this = make_static_this c p in
-		mk (TField(e_this,FStatic(c,cf))) cf.cf_type p
+	let make_static_field_access c cf t p =
+		let ethis = make_static_this c p in
+		mk (TField (ethis,(FStatic (c,cf)))) t p
 
 
 	let make_throw e p =
 	let make_throw e p =
 		mk (TThrow e) t_dynamic p
 		mk (TThrow e) t_dynamic p
@@ -505,7 +517,7 @@ module Builder = struct
 		| TFloat f -> mk (TConst (TFloat f)) basic.tfloat p
 		| TFloat f -> mk (TConst (TFloat f)) basic.tfloat p
 		| TBool b -> mk (TConst (TBool b)) basic.tbool p
 		| TBool b -> mk (TConst (TBool b)) basic.tbool p
 		| TNull -> mk (TConst TNull) (basic.tnull (mk_mono())) p
 		| TNull -> mk (TConst TNull) (basic.tnull (mk_mono())) p
-		| _ -> typing_error "Unsupported constant" p
+		| _ -> raise_typing_error "Unsupported constant" p
 
 
 	let field e name t p =
 	let field e name t p =
 		let f =
 		let f =
@@ -572,7 +584,7 @@ let replace_separators s c =
 let type_constant basic c p =
 let type_constant basic c p =
 	match c with
 	match c with
 	| Int (s,_) ->
 	| Int (s,_) ->
-		if String.length s > 10 && String.sub s 0 2 = "0x" then typing_error "Invalid hexadecimal integer" p;
+		if String.length s > 10 && String.sub s 0 2 = "0x" then raise_typing_error "Invalid hexadecimal integer" p;
 		(try mk (TConst (TInt (Int32.of_string s))) basic.tint p
 		(try mk (TConst (TInt (Int32.of_string s))) basic.tint p
 		with _ -> mk (TConst (TFloat s)) basic.tfloat p)
 		with _ -> mk (TConst (TFloat s)) basic.tfloat p)
 	| Float (f,_) -> mk (TConst (TFloat f)) basic.tfloat p
 	| Float (f,_) -> mk (TConst (TFloat f)) basic.tfloat p
@@ -580,8 +592,8 @@ let type_constant basic c p =
 	| Ident "true" -> mk (TConst (TBool true)) basic.tbool p
 	| Ident "true" -> mk (TConst (TBool true)) basic.tbool p
 	| Ident "false" -> mk (TConst (TBool false)) basic.tbool p
 	| Ident "false" -> mk (TConst (TBool false)) basic.tbool p
 	| Ident "null" -> mk (TConst TNull) (basic.tnull (mk_mono())) p
 	| Ident "null" -> mk (TConst TNull) (basic.tnull (mk_mono())) p
-	| Ident t -> typing_error ("Invalid constant :  " ^ t) p
-	| Regexp _ -> typing_error "Invalid constant" p
+	| Ident t -> raise_typing_error ("Invalid constant :  " ^ t) p
+	| Regexp _ -> raise_typing_error "Invalid constant" p
 
 
 let rec type_constant_value basic (e,p) =
 let rec type_constant_value basic (e,p) =
 	match e with
 	match e with
@@ -594,16 +606,16 @@ let rec type_constant_value basic (e,p) =
 	| EArrayDecl el ->
 	| EArrayDecl el ->
 		mk (TArrayDecl (List.map (type_constant_value basic) el)) (basic.tarray t_dynamic) p
 		mk (TArrayDecl (List.map (type_constant_value basic) el)) (basic.tarray t_dynamic) p
 	| _ ->
 	| _ ->
-		typing_error "Constant value expected" p
+		raise_typing_error "Constant value expected" p
 
 
 let is_constant_value basic e =
 let is_constant_value basic e =
-	try (ignore (type_constant_value basic e); true) with Error (Custom _,_,_) -> false
+	try (ignore (type_constant_value basic e); true) with Error {err_message = Custom _} -> false
 
 
 let for_remap basic v e1 e2 p =
 let for_remap basic v e1 e2 p =
 	let v' = alloc_var v.v_kind v.v_name e1.etype e1.epos in
 	let v' = alloc_var v.v_kind v.v_name e1.etype e1.epos in
 	let ev' = mk (TLocal v') e1.etype e1.epos in
 	let ev' = mk (TLocal v') e1.etype e1.epos in
 	let t1 = (Abstract.follow_with_abstracts e1.etype) in
 	let t1 = (Abstract.follow_with_abstracts e1.etype) in
-	let ehasnext = mk (TField(ev',try quick_field t1 "hasNext" with Not_found -> typing_error (s_type (print_context()) t1 ^ "has no field hasNext()") p)) (tfun [] basic.tbool) e1.epos in
+	let ehasnext = mk (TField(ev',try quick_field t1 "hasNext" with Not_found -> raise_typing_error (s_type (print_context()) t1 ^ "has no field hasNext()") p)) (tfun [] basic.tbool) e1.epos in
 	let ehasnext = mk (TCall(ehasnext,[])) basic.tbool ehasnext.epos in
 	let ehasnext = mk (TCall(ehasnext,[])) basic.tbool ehasnext.epos in
 	let enext = mk (TField(ev',quick_field t1 "next")) (tfun [] v.v_type) e1.epos in
 	let enext = mk (TField(ev',quick_field t1 "next")) (tfun [] v.v_type) e1.epos in
 	let enext = mk (TCall(enext,[])) v.v_type e1.epos in
 	let enext = mk (TCall(enext,[])) v.v_type e1.epos in
@@ -638,7 +650,7 @@ let build_metadata api t =
 	let make_meta_field ml =
 	let make_meta_field ml =
 		let h = Hashtbl.create 0 in
 		let h = Hashtbl.create 0 in
 		mk (TObjectDecl (List.map (fun (f,el,p) ->
 		mk (TObjectDecl (List.map (fun (f,el,p) ->
-			if Hashtbl.mem h f then typing_error ("Duplicate metadata '" ^ f ^ "'") p;
+			if Hashtbl.mem h f then raise_typing_error ("Duplicate metadata '" ^ f ^ "'") p;
 			Hashtbl.add h f ();
 			Hashtbl.add h f ();
 			(f,null_pos,NoQuotes), mk (match el with [] -> TConst TNull | _ -> TArrayDecl (List.map (type_constant_value api) el)) (api.tarray t_dynamic) p
 			(f,null_pos,NoQuotes), mk (match el with [] -> TConst TNull | _ -> TArrayDecl (List.map (type_constant_value api) el)) (api.tarray t_dynamic) p
 		) ml)) t_dynamic p
 		) ml)) t_dynamic p
@@ -732,14 +744,14 @@ let dump_with_pos tabs e =
 			add "TWhile";
 			add "TWhile";
 			loop e1;
 			loop e1;
 			loop e2;
 			loop e2;
-		| TSwitch(e1,cases,def) ->
+		| TSwitch switch ->
 			add "TSwitch";
 			add "TSwitch";
-			loop e1;
-			List.iter (fun (el,e) ->
-				List.iter (loop' (tabs ^ "    ")) el;
-				loop' (tabs ^ "      ") e;
-			) cases;
-			Option.may (loop' (tabs ^ "      ")) def
+			loop switch.switch_subject;
+			List.iter (fun case ->
+				List.iter (loop' (tabs ^ "    ")) case.case_patterns;
+				loop' (tabs ^ "      ") case.case_expr;
+			) switch.switch_cases;
+			Option.may (loop' (tabs ^ "      ")) switch.switch_default
 		| TTry(e1,catches) ->
 		| TTry(e1,catches) ->
 			add "TTry";
 			add "TTry";
 			loop e1;
 			loop e1;
@@ -843,13 +855,15 @@ let punion_el default_pos el =
 		else
 		else
 			punion first last
 			punion first last
 
 
-let is_exhaustive e1 def =
-	let rec loop e1 = match e1.eexpr with
-		| TMeta((Meta.Exhaustive,_,_),_) -> true
-		| TMeta(_, e1) | TParenthesis e1 -> loop e1
-		| _ -> false
-	in
-	def <> None || loop e1
+let is_exhaustive switch =
+	switch.switch_exhaustive
+
+let mk_switch subject cases default exhaustive = {
+	switch_subject = subject;
+	switch_cases = cases;
+	switch_default = default;
+	switch_exhaustive = exhaustive;
+}
 
 
 let rec is_true_expr e1 = match e1.eexpr with
 let rec is_true_expr e1 = match e1.eexpr with
 	| TConst(TBool true) -> true
 	| TConst(TBool true) -> true
@@ -890,15 +904,15 @@ module DeadEnd = struct
 				loop cond || loop if_body && loop else_body
 				loop cond || loop if_body && loop else_body
 			| TIf (cond, _, None) ->
 			| TIf (cond, _, None) ->
 				loop cond
 				loop cond
-			| TSwitch(e1, cases, def) ->
+			| TSwitch switch ->
 				let check_exhaustive () =
 				let check_exhaustive () =
-					(is_exhaustive e1 def) && List.for_all (fun (el,e) ->
-						List.exists loop el ||
-						loop e
-					) cases &&
-					Option.map_default (loop ) true def (* true because we know it's exhaustive *)
+					(is_exhaustive switch) && List.for_all (fun case ->
+						List.exists loop case.case_patterns ||
+						loop case.case_expr
+					) switch.switch_cases &&
+					Option.map_default (loop ) true switch.switch_default (* true because we know it's exhaustive *)
 				in
 				in
-				loop e1 || check_exhaustive ()
+				loop switch.switch_subject || check_exhaustive ()
 			| TFor(_, e1, _) ->
 			| TFor(_, e1, _) ->
 				loop e1
 				loop e1
 			| TBinop(OpBoolAnd, e1, e2) ->
 			| TBinop(OpBoolAnd, e1, e2) ->

+ 4 - 2
src/core/timer.ml

@@ -92,6 +92,8 @@ let close = close (get_time())
 
 
 (* Printing *)
 (* Printing *)
 
 
+let timer_threshold = 0.01
+
 type timer_node = {
 type timer_node = {
 	name : string;
 	name : string;
 	path : string;
 	path : string;
@@ -168,7 +170,7 @@ let build_times_tree () =
 		) node.children;
 		) node.children;
 		node.children <- List.sort (fun node1 node2 -> compare node2.time node1.time) node.children;
 		node.children <- List.sort (fun node1 node2 -> compare node2.time node1.time) node.children;
 		if node.num_calls > !max_calls then max_calls := node.num_calls;
 		if node.num_calls > !max_calls then max_calls := node.num_calls;
-		if node.time > 0.0009 && l > !max_name then max_name := l;
+		if node.time >= timer_threshold && l > !max_name then max_name := l;
 	in
 	in
 	loop 0 root;
 	loop 0 root;
 	!max_name,!max_calls,root
 	!max_name,!max_calls,root
@@ -180,7 +182,7 @@ let report_times print =
 	let sep = String.make (max_name + max_calls + 27) '-' in
 	let sep = String.make (max_name + max_calls + 27) '-' in
 	print sep;
 	print sep;
 	let print_time name node =
 	let print_time name node =
-		if node.time > 0.0009 then
+		if node.time >= timer_threshold then
 			print (Printf.sprintf "%-*s | %7.3f | %3.0f | %3.0f | %*i | %s" max_name name node.time (node.time *. 100. /. root.time) (node.time *. 100. /. node.parent.time) max_calls node.num_calls node.info)
 			print (Printf.sprintf "%-*s | %7.3f | %3.0f | %3.0f | %*i | %s" max_name name node.time (node.time *. 100. /. root.time) (node.time *. 100. /. node.parent.time) max_calls node.num_calls node.info)
 	in
 	in
 	let rec loop depth node =
 	let rec loop depth node =

+ 3 - 3
src/core/warning.ml

@@ -13,7 +13,7 @@ type warning_option = {
 
 
 let parse_options s ps lexbuf =
 let parse_options s ps lexbuf =
 	let fail msg p =
 	let fail msg p =
-		Error.typing_error msg {p with pmin = ps.pmin + p.pmin; pmax = ps.pmin + p.pmax}
+		raise_typing_error msg {p with pmin = ps.pmin + p.pmin; pmax = ps.pmin + p.pmax}
 	in
 	in
 	let parse_string s p =
 	let parse_string s p =
 		begin try
 		begin try
@@ -58,7 +58,7 @@ let from_meta ml =
 			let p = snd e in
 			let p = snd e in
 			parse_options s {p with pmin = p.pmin + 1; pmax = p.pmax - 1} (* pmin is on the quote *)
 			parse_options s {p with pmin = p.pmin + 1; pmax = p.pmax - 1} (* pmin is on the quote *)
 		| _ ->
 		| _ ->
-			Error.typing_error "String expected" (snd e)
+			raise_typing_error "String expected" (snd e)
 	in
 	in
 	let rec loop acc ml = match ml with
 	let rec loop acc ml = match ml with
 		| (Meta.HaxeWarning,args,_) :: ml ->
 		| (Meta.HaxeWarning,args,_) :: ml ->
@@ -92,4 +92,4 @@ let get_mode w (l : warning_option list list) =
 			in
 			in
 			loop (loop2 mode l2) l
 			loop (loop2 mode l2) l
 	in
 	in
-	loop WMEnable (* ? *) l
+	loop WMEnable (* ? *) l

+ 13 - 5
src/dune

@@ -2,17 +2,25 @@
 
 
 (env
 (env
 	(_
 	(_
-		(flags (:standard -w -3 -w -23 -thread))
+		; 3 - Remove deprecation warnings
+		; 6 - Label omitted in function application
+		; 9 - Missing record field in a record pattern
+		; 23 - Useless record `with` clause (all fields already listed)
+		; 27 - Unused var (strict)
+		; 32 - Unused value declaration
+		; 36 - Unused `as super`
+		; 50 - Unexpected docstring
+		(flags (:standard -w -3 -w -6 -w -9 -w -23 -w -27 -w -32 -w -36 -w -50 -thread))
 	)
 	)
 )
 )
 
 
 (library
 (library
 	(name haxe)
 	(name haxe)
 	(libraries
 	(libraries
-		extc extproc extlib_leftovers mbedtls neko objsize pcre2 swflib ttflib ziplib
+		extc extproc extlib_leftovers mbedtls neko objsize pcre2 camlp-streams swflib ttflib ziplib
 		json
 		json
-		unix str bigarray threads dynlink
-		xml-light extlib ptmap sha
+		unix ipaddr str bigarray threads dynlink
+		xml-light extlib sha
 		luv
 		luv
 	)
 	)
 	(modules (:standard \ haxe))
 	(modules (:standard \ haxe))
@@ -31,4 +39,4 @@
 	(link_flags (:include ../lib.sexp))
 	(link_flags (:include ../lib.sexp))
 	; Uncomment to enable bytecode output for ocamldebug support
 	; Uncomment to enable bytecode output for ocamldebug support
 	; (modes byte)
 	; (modes byte)
-)
+)

+ 0 - 1
src/filters/defaultArguments.ml

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

Some files were not shown because too many files changed in this diff