haxe_3.2.1+dfsg.orig/.travis.yml 0000664 0001750 0001750 00000004666 12607337712 016451 0 ustar andy andy 0000000 0000000 language: cpp
os:
- linux
- osx
env:
global:
# make variables
- OCAMLC=ocamlc.opt
- OCAMLOPT=ocamlopt.opt
- ADD_REVISION=1
# SAUCE_USERNAME
- secure: SjyKefmjUEXi0IKHGGpcbLAajU0mLHONg8aA8LoY7Q9nAkSN6Aql+fzS38Boq7w1jWn+2FOpr+4jy0l6wVd/bftsF+huFfYpFJmdh8BlKmE0K71zZAral0H1c7YxkuQpPiJCIFGXqtkvev7SWTy0z31u7kuuQeEyW27boXe5cDA=
# SAUCE_ACCESS_KEY
- secure: sUvWUjCyPuWht4seNa4f2VG9DkvXkhZyLZfjJO9TUAHB2JndS16E2j/qrvKEjycyH6w8tU/B9vnjDRvvGrYXxEXcBEwsJVfkorFnRl9uwGCGIYrzjMhssEl3fMYZK7P304f+gAp5ULrDBX2gIaKeSa8lUNRtz2PsZOieE4kMdhk=
matrix:
- TEST=third-party
- TEST=macro
- TEST=neko
- TEST=js
- TEST=php
- TEST=cpp
- TEST=flash9
- TEST=as3
- TEST=java
- TEST=cs
- TEST=python
matrix:
# fast_finish: true #https://github.com/travis-ci/travis-ci/issues/1696
before_script:
- if [ "${TRAVIS_OS_NAME}" = "linux" ]; then
mysql -u root -e "CREATE DATABASE haxe_test;";
fi
install:
# For our forks that do not have mult-os enabled...
- if [ -z "${TRAVIS_OS_NAME}" ]; then
export TRAVIS_OS_NAME=linux;
fi
# Install haxe and neko dependencies
- if [ "${TRAVIS_OS_NAME}" = "linux" ]; then
travis_retry sudo apt-get update -qq;
travis_retry sudo apt-get install ocaml-native-compilers zlib1g-dev libgc-dev -qq;
fi
- if [ "${TRAVIS_OS_NAME}" = "osx" ]; then
travis_retry brew update;
travis_retry brew install caskroom/cask/brew-cask;
travis_retry brew install ocaml camlp4;
fi
# Install neko
- if [ "${TRAVIS_OS_NAME}" = "linux" ]; then
travis_retry git clone https://github.com/HaxeFoundation/neko.git ~/neko;
cd ~/neko && make os=${TRAVIS_OS_NAME} -s && sudo make install -s;
cd $TRAVIS_BUILD_DIR;
fi
- if [ "${TRAVIS_OS_NAME}" = "osx" ]; then
travis_retry brew install neko --HEAD;
fi
script:
- make -s
- make tools -s
- sudo make install -s
- cd tests/
- mkdir ~/haxelib && haxelib setup ~/haxelib
- haxe -version
- haxe RunCi.hxml
- neko RunCi.n
branches:
except:
# A hack to prevent building for tags, assuming they all start with a number.
# https://github.com/travis-ci/travis-ci/issues/1532
- /^[0-9]/
notifications:
webhooks:
urls:
- https://webhooks.gitter.im/e/95a5fa471c27beee8e7c
on_success: change # options: [always|never|change] default: always
on_failure: always # options: [always|never|change] default: always
on_start: false # default: false
haxe_3.2.1+dfsg.orig/CONTRIBUTING.md 0000664 0001750 0001750 00000002702 12607337712 016556 0 ustar andy andy 0000000 0000000 Things to check before/while filing an issue:
- Check if you actually suspect that there's an issue in the Haxe code. If you find yourself writing "How do I..." you may want to consider a different communication channel. Refer to http://haxe.org/community/community-support.html for more information.
- Reduce your code to a minimal example (see http://sscce.org/). In particular avoid library dependencies: If you cannot reproduce your issue without using a specific library, it might not be a Haxe issue to begin with.
- Check if your problems are already resolved in the Haxe development version (for builds see http://builds.haxe.org/).
- Most targets produce readable code. If you suspect the generated code to be wrong, try checking the output. Note that you can add `-D dump=pretty` to your compilation parameters and find the code which is passed to the generators in a `dump` sub directory.
Other remarks:
- Sometimes people try to be particularly helpful by not only including broken parts in their code, but also "similar" code which is working. More often than not this is more distracting than helpful. If you want to highlight something like this, consider adding the working code commented out.
- We do not require a classic "What do you see/what do you expect?" form, but in some cases it is hard to figure out where you think the actual problem is otherwise.
- We're keeping this page quite short so there's a higher chance that people actually read it.
haxe_3.2.1+dfsg.orig/Makefile 0000664 0001750 0001750 00000022540 12607337712 015767 0 ustar andy andy 0000000 0000000 # Haxe compiler Makefile
#
# - use 'make' to build all
# - use 'make haxe' to build only the compiler (not the libraries)
# - if you want to build quickly, install 'ocamlopt.opt' and change OCAMLOPT=ocamlopt.opt
#
# Windows users :
# - use 'make -f Makefile.win' to build for Windows
# - use 'make MSVC=1 -f Makefile.win' to build for Windows with OCaml/MSVC
#
.SUFFIXES : .ml .mli .cmo .cmi .cmx .mll .mly
INSTALL_DIR=/usr
INSTALL_BIN_DIR=$(INSTALL_DIR)/bin
INSTALL_LIB_DIR=$(INSTALL_DIR)/lib/haxe
OUTPUT=haxe
EXTENSION=
OCAMLOPT?=ocamlopt
OCAMLC?=ocamlc
LFLAGS=
CFLAGS= -g -I libs/extlib -I libs/extc -I libs/neko -I libs/javalib -I libs/ziplib -I libs/swflib -I libs/xml-light -I libs/ttflib -I libs/ilib -I libs/objsize
LIBS=unix str libs/extlib/extLib libs/xml-light/xml-light libs/swflib/swflib \
libs/extc/extc libs/neko/neko libs/javalib/java libs/ziplib/zip \
libs/ttflib/ttf libs/ilib/il libs/objsize/objsize
NATIVE_LIBS=-cclib libs/extc/extc_stubs.o -cclib libs/extc/process_stubs.o -cclib -lz -cclib libs/objsize/c_objsize.o
ifeq ($(BYTECODE),1)
TARGET_FLAG = bytecode
COMPILER = $(OCAMLC)
LIB_EXT = cma
MODULE_EXT = cmo
NATIVE_LIB_FLAG = -custom
else
TARGET_FLAG = native
COMPILER = $(OCAMLOPT)
LIB_EXT = cmxa
MODULE_EXT = cmx
endif
CC_CMD = $(COMPILER) $(CFLAGS) -c $<
CC_PARSER_CMD = $(COMPILER) -pp camlp4o $(CFLAGS) -c parser.ml
RELDIR=../../..
MODULES=ast type lexer common genxml parser typecore optimizer typeload \
codegen gencommon genas3 gencpp genjs genneko genphp \
genswf9 genswf genjava gencs genpy interp dce analyzer filters typer matcher version main
ADD_REVISION?=0
BRANCH=$(shell echo $$APPVEYOR_REPO_NAME | grep -q /haxe && echo $$APPVEYOR_REPO_BRANCH || echo $$TRAVIS_REPO_SLUG | grep -q /haxe && echo $$TRAVIS_BRANCH || git rev-parse --abbrev-ref HEAD)
COMMIT_SHA=$(shell git rev-parse --short HEAD)
COMMIT_DATE=$(shell git show -s --format=%ci HEAD | grep -oh ....-..-..)
PACKAGE_FILE_NAME=haxe_$(COMMIT_DATE)_$(BRANCH)_$(COMMIT_SHA)
# using $(CURDIR) on Windows will not work since it might be a Cygwin path
ifdef SYSTEMROOT
EXTENSION=.exe
else
export HAXE_STD_PATH=$(CURDIR)/std
endif
all: libs haxe
libs:
make -C libs/extlib OCAMLOPT=$(OCAMLOPT) OCAMLC=$(OCAMLC) $(TARGET_FLAG)
make -C libs/extc OCAMLOPT=$(OCAMLOPT) OCAMLC=$(OCAMLC) $(TARGET_FLAG)
make -C libs/neko OCAMLOPT=$(OCAMLOPT) OCAMLC=$(OCAMLC) $(TARGET_FLAG)
make -C libs/javalib OCAMLOPT=$(OCAMLOPT) OCAMLC=$(OCAMLC) $(TARGET_FLAG)
make -C libs/ilib OCAMLOPT=$(OCAMLOPT) OCAMLC=$(OCAMLC) $(TARGET_FLAG)
make -C libs/ziplib OCAMLOPT=$(OCAMLOPT) OCAMLC=$(OCAMLC) $(TARGET_FLAG)
make -C libs/swflib OCAMLOPT=$(OCAMLOPT) OCAMLC=$(OCAMLC) $(TARGET_FLAG)
make -C libs/xml-light OCAMLOPT=$(OCAMLOPT) OCAMLC=$(OCAMLC) $(TARGET_FLAG)
make -C libs/ttflib OCAMLOPT=$(OCAMLOPT) OCAMLC=$(OCAMLC) $(TARGET_FLAG)
make -C libs/objsize OCAMLOPT=$(OCAMLOPT) OCAMLC=$(OCAMLC) $(TARGET_FLAG)
haxe: $(MODULES:=.$(MODULE_EXT))
$(COMPILER) -o $(OUTPUT) $(NATIVE_LIBS) $(NATIVE_LIB_FLAG) $(LFLAGS) $(LIBS:=.$(LIB_EXT)) $(MODULES:=.$(MODULE_EXT))
haxelib:
(cd $(CURDIR)/extra/haxelib_src && $(CURDIR)/$(OUTPUT) haxelib.hxml && nekotools boot bin/haxelib.n)
cp extra/haxelib_src/bin/haxelib$(EXTENSION) haxelib$(EXTENSION)
tools: haxelib
install:
-rm -f $(INSTALL_LIB_DIR)
-mkdir -p $(INSTALL_LIB_DIR)
rm -rf $(INSTALL_LIB_DIR)/std
cp -rf std $(INSTALL_LIB_DIR)/std
cp -rf extra $(INSTALL_LIB_DIR)
-mkdir -p $(INSTALL_LIB_DIR)/lib
rm -f $(INSTALL_BIN_DIR)/haxe
cp haxe $(INSTALL_LIB_DIR)
ln -s $(INSTALL_LIB_DIR)/haxe $(INSTALL_BIN_DIR)/haxe
chmod -R a+rx $(INSTALL_LIB_DIR)
chmod 777 $(INSTALL_LIB_DIR)/lib
# cp extra/haxelib_src/haxelib_script.sh $(INSTALL_DIR)/bin/haxelib
echo "#!/bin/sh" > $(INSTALL_BIN_DIR)/haxelib
echo "exec haxe -cp $(INSTALL_LIB_DIR)/extra/haxelib_src/src --run tools.haxelib.Main \"\$$@\"" >> $(INSTALL_BIN_DIR)/haxelib
chmod a+rx $(INSTALL_BIN_DIR)/haxe $(INSTALL_BIN_DIR)/haxelib
# will install native version of the tools instead of script ones
install_tools: tools
cp haxelib ${INSTALL_BIN_DIR}/haxelib
chmod a+rx $(INSTALL_BIN_DIR)/haxelib
uninstall:
rm -rf $(INSTALL_BIN_DIR)/haxe $(INSTALL_BIN_DIR)/haxelib $(INSTALL_LIB_DIR)
# Modules
analyzer.$(MODULE_EXT): ast.$(MODULE_EXT) type.$(MODULE_EXT) common.$(MODULE_EXT) codegen.$(MODULE_EXT)
codegen.$(MODULE_EXT): optimizer.$(MODULE_EXT) typeload.$(MODULE_EXT) typecore.$(MODULE_EXT) type.$(MODULE_EXT) genxml.$(MODULE_EXT) common.$(MODULE_EXT) ast.$(MODULE_EXT)
common.$(MODULE_EXT): type.$(MODULE_EXT) ast.$(MODULE_EXT) libs/ilib/il.$(LIB_EXT)
dce.$(MODULE_EXT): ast.$(MODULE_EXT) common.$(MODULE_EXT) codegen.$(MODULE_EXT) type.$(MODULE_EXT)
filters.$(MODULE_EXT): ast.$(MODULE_EXT) analyzer.$(MODULE_EXT) common.$(MODULE_EXT) type.$(MODULE_EXT) dce.$(MODULE_EXT) codegen.$(MODULE_EXT) typecore.$(MODULE_EXT)
genas3.$(MODULE_EXT): type.$(MODULE_EXT) common.$(MODULE_EXT) codegen.$(MODULE_EXT) ast.$(MODULE_EXT)
gencommon.$(MODULE_EXT): type.$(MODULE_EXT) common.$(MODULE_EXT) codegen.$(MODULE_EXT) ast.$(MODULE_EXT) libs/ilib/il.$(LIB_EXT)
gencpp.$(MODULE_EXT): type.$(MODULE_EXT) lexer.$(MODULE_EXT) common.$(MODULE_EXT) codegen.$(MODULE_EXT) ast.$(MODULE_EXT) gencommon.$(MODULE_EXT)
gencs.$(MODULE_EXT): type.$(MODULE_EXT) lexer.$(MODULE_EXT) gencommon.$(MODULE_EXT) common.$(MODULE_EXT) codegen.$(MODULE_EXT) ast.$(MODULE_EXT) libs/ilib/il.$(LIB_EXT)
genjava.$(MODULE_EXT): type.$(MODULE_EXT) gencommon.$(MODULE_EXT) common.$(MODULE_EXT) codegen.$(MODULE_EXT) ast.$(MODULE_EXT)
genjs.$(MODULE_EXT): type.$(MODULE_EXT) optimizer.$(MODULE_EXT) lexer.$(MODULE_EXT) common.$(MODULE_EXT) codegen.$(MODULE_EXT) ast.$(MODULE_EXT)
genneko.$(MODULE_EXT): type.$(MODULE_EXT) lexer.$(MODULE_EXT) common.$(MODULE_EXT) codegen.$(MODULE_EXT) ast.$(MODULE_EXT)
genphp.$(MODULE_EXT): type.$(MODULE_EXT) lexer.$(MODULE_EXT) common.$(MODULE_EXT) codegen.$(MODULE_EXT) ast.$(MODULE_EXT)
genpy.$(MODULE_EXT): type.$(MODULE_EXT) lexer.$(MODULE_EXT) common.$(MODULE_EXT) codegen.$(MODULE_EXT) ast.$(MODULE_EXT)
genswf.$(MODULE_EXT): type.$(MODULE_EXT) genswf9.$(MODULE_EXT) common.$(MODULE_EXT) ast.$(MODULE_EXT)
genswf9.$(MODULE_EXT): type.$(MODULE_EXT) lexer.$(MODULE_EXT) common.$(MODULE_EXT) codegen.$(MODULE_EXT) ast.$(MODULE_EXT)
genxml.$(MODULE_EXT): type.$(MODULE_EXT) lexer.$(MODULE_EXT) common.$(MODULE_EXT) ast.$(MODULE_EXT)
interp.$(MODULE_EXT): typecore.$(MODULE_EXT) type.$(MODULE_EXT) lexer.$(MODULE_EXT) genneko.$(MODULE_EXT) common.$(MODULE_EXT) codegen.$(MODULE_EXT) ast.$(MODULE_EXT) genswf.$(MODULE_EXT) genjava.$(MODULE_EXT) gencs.$(MODULE_EXT) parser.$(MODULE_EXT) libs/ilib/il.$(LIB_EXT)
matcher.$(MODULE_EXT): optimizer.$(MODULE_EXT) codegen.$(MODULE_EXT) typecore.$(MODULE_EXT) type.$(MODULE_EXT) typer.$(MODULE_EXT) common.$(MODULE_EXT) ast.$(MODULE_EXT)
main.$(MODULE_EXT): filters.$(MODULE_EXT) matcher.$(MODULE_EXT) typer.$(MODULE_EXT) typeload.$(MODULE_EXT) typecore.$(MODULE_EXT) type.$(MODULE_EXT) parser.$(MODULE_EXT) optimizer.$(MODULE_EXT) lexer.$(MODULE_EXT) interp.$(MODULE_EXT) genxml.$(MODULE_EXT) genswf.$(MODULE_EXT) genphp.$(MODULE_EXT) genneko.$(MODULE_EXT) genjs.$(MODULE_EXT) gencpp.$(MODULE_EXT) genas3.$(MODULE_EXT) common.$(MODULE_EXT) codegen.$(MODULE_EXT) ast.$(MODULE_EXT) gencommon.$(MODULE_EXT) genjava.$(MODULE_EXT) gencs.$(MODULE_EXT) genpy.$(MODULE_EXT) version.$(MODULE_EXT) libs/ilib/il.$(LIB_EXT)
optimizer.$(MODULE_EXT): typecore.$(MODULE_EXT) type.$(MODULE_EXT) parser.$(MODULE_EXT) common.$(MODULE_EXT) ast.$(MODULE_EXT)
parser.$(MODULE_EXT): parser.ml lexer.$(MODULE_EXT) common.$(MODULE_EXT) ast.$(MODULE_EXT)
$(CC_PARSER_CMD)
type.$(MODULE_EXT): ast.$(MODULE_EXT)
typecore.$(MODULE_EXT): type.$(MODULE_EXT) common.$(MODULE_EXT) ast.$(MODULE_EXT)
typeload.$(MODULE_EXT): typecore.$(MODULE_EXT) type.$(MODULE_EXT) parser.$(MODULE_EXT) optimizer.$(MODULE_EXT) lexer.$(MODULE_EXT) common.$(MODULE_EXT) ast.$(MODULE_EXT)
typer.$(MODULE_EXT): typeload.$(MODULE_EXT) typecore.$(MODULE_EXT) type.$(MODULE_EXT) parser.$(MODULE_EXT) optimizer.$(MODULE_EXT) lexer.$(MODULE_EXT) interp.$(MODULE_EXT) genneko.$(MODULE_EXT) genjs.$(MODULE_EXT) common.$(MODULE_EXT) codegen.$(MODULE_EXT) ast.$(MODULE_EXT) filters.$(MODULE_EXT) gencommon.$(MODULE_EXT)
lexer.$(MODULE_EXT): lexer.ml
lexer.$(MODULE_EXT): ast.$(MODULE_EXT)
ast.$(MODULE_EXT):
version.$(MODULE_EXT):
$(MAKE) -f Makefile.version_extra -s ADD_REVISION=$(ADD_REVISION) BRANCH=$(BRANCH) COMMIT_SHA=$(COMMIT_SHA) COMMIT_DATE=$(COMMIT_DATE) > version.ml
$(COMPILER) $(CFLAGS) -c version.ml
# Package
package_bin:
mkdir -p out
rm -rf $(PACKAGE_FILE_NAME) $(PACKAGE_FILE_NAME).tar.gz
# Copy the package contents to $(PACKAGE_FILE_NAME)
mkdir -p $(PACKAGE_FILE_NAME)
cp -r $(OUTPUT) haxelib$(EXTENSION) std extra/LICENSE.txt extra/CONTRIB.txt extra/CHANGES.txt $(PACKAGE_FILE_NAME)
# archive
tar -zcf out/$(PACKAGE_FILE_NAME).tar.gz $(PACKAGE_FILE_NAME)
rm -r $(PACKAGE_FILE_NAME)
# Clean
clean: clean_libs clean_haxe clean_tools
clean_libs:
make -C libs/extlib clean
make -C libs/extc clean
make -C libs/neko clean
make -C libs/ziplib clean
make -C libs/javalib clean
make -C libs/ilib clean
make -C libs/swflib clean
make -C libs/xml-light clean
make -C libs/ttflib clean
make -C libs/objsize clean
clean_haxe:
rm -f $(MODULES:=.obj) $(MODULES:=.o) $(MODULES:=.cmx) $(MODULES:=.cmi) $(MODULES:=.cmo) lexer.ml $(OUTPUT)
clean_tools:
rm -f $(OUTPUT) haxelib
# SUFFIXES
.ml.cmx:
$(CC_CMD)
.ml.cmo:
$(CC_CMD)
.mll.ml:
ocamllex $<
.PHONY: haxe libs version.cmx version.cmo haxelib
haxe_3.2.1+dfsg.orig/Makefile.version_extra 0000664 0001750 0001750 00000000666 12607337712 020663 0 ustar andy andy 0000000 0000000 # A hack to print the content of version.ml consistently across Windows (cygwin / command prompt) and Unix.
# The hack: http://stackoverflow.com/a/7284135/267998
# The issue: https://github.com/HaxeFoundation/haxe/commit/4f8f6a99ddf810ea045492cdd6d40c55abc03e15#commitcomment-10660400
all: ;
ifneq ($(ADD_REVISION),0)
$(info let version_extra = Some "(git build $(BRANCH) @ $(COMMIT_SHA))")
else
$(info let version_extra = None)
endif haxe_3.2.1+dfsg.orig/Makefile.win 0000664 0001750 0001750 00000003244 12607337712 016563 0 ustar andy andy 0000000 0000000 include Makefile
OUTPUT=haxe.exe
EXTENSION=.exe
OCAMLOPT=ocamlopt.opt
kill:
-@taskkill /F /IM haxe.exe
# allow Ocaml/Mingw as well
NATIVE_LIBS += -I "c:/program files/mingw/lib/"
# use make WODI=wodi32 -f Makefile.win to build using WODI 32bit
ifdef WODI
NATIVE_LIBS += -I "/opt/${WODI}/lib"
endif
# use make MSVC=1 -f Makefile.win to build for OCaml/MSVC
ifeq (${MSVC}, 1)
NATIVE_LIBS = shell32.lib libs/extc/extc_stubs.obj libs/extc/process_stubs.obj libs/extc/zlib/zlib.lib libs/objsize/c_objsize.obj
endif
ifeq (${MSVC_OUTPUT}, 1)
FILTER=sed 's/File "\([^"]\+\)", line \([0-9]\+\), \(.*\)/\1(\2): \3/' tmp.cmi
endif
ifeq (${FD_OUTPUT}, 1)
FILTER=sed '/File/{ N; s/File "\([^"]\+\)", line \([0-9]\+\), characters \([0-9-]\+\):[\r\n]*\(.*\)/\1:\2: characters \3 : \4/ }' tmp.cmi
endif
ifdef FILTER
CC_CMD=($(OCAMLOPT) $(CFLAGS) -c $< 2>tmp.cmi && $(FILTER)) || ($(FILTER) && exit 1)
CC_PARSER_CMD=($(OCAMLOPT) -pp camlp4o $(CFLAGS) -c parser.ml 2>tmp.cmi && $(FILTER)) || ($(FILTER) && exit 1)
endif
package_bin:
mkdir -p out
rm -rf $(PACKAGE_FILE_NAME) $(PACKAGE_FILE_NAME).zip temp.zip
# Copy the package contents to $(PACKAGE_FILE_NAME)
# Using poor man's cp (zip then unzip), because cp in cygwin is quite broken
mkdir -p $(PACKAGE_FILE_NAME)
7za a -y -tzip -mx0 temp.zip $(OUTPUT) haxelib$(EXTENSION) std > log.txt || type log.txt
cd extra && 7za a -y -tzip -mx0 ../temp.zip LICENSE.txt CONTRIB.txt CHANGES.txt > log.txt || type log.txt
7za x -y temp.zip -o$(PACKAGE_FILE_NAME) > log.txt || type log.txt
rm temp.zip
# archive
7za a -r -tzip out/$(PACKAGE_FILE_NAME).zip $(PACKAGE_FILE_NAME) > log.txt || type log.txt
rm -r $(PACKAGE_FILE_NAME)
rm log.txt extra/log.txt haxe_3.2.1+dfsg.orig/README.md 0000664 0001750 0001750 00000007652 12607337712 015615 0 ustar andy andy 0000000 0000000
# [](http://haxe.org) - [The Cross-Platform Toolkit](http://haxe.org)
[](https://travis-ci.org/HaxeFoundation/haxe)
[](https://ci.appveyor.com/project/HaxeFoundation/haxe)
[](https://saucelabs.com/u/haxe)
[](https://gitter.im/HaxeFoundation/haxe?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge)
Haxe is an open source toolkit that allows you to easily build cross-platform tools and applications that target many mainstream platforms. The Haxe toolkit includes:
* **The Haxe programming language**, a modern, high-level, strictly-typed programming language
* **The Haxe cross-compiler**, a state-of-the-art, lightning-speed compiler for many targets
* **The Haxe standard library**, a complete, cross-platform library of common functionality
Haxe allows you to compile for the following targets:
* ActionScript 3
* C++
* C#
* Flash
* Java
* JavaScript
* NekoVM
* PHP
* Python
You can try Haxe directly from your browser at [try.haxe.org](http://try.haxe.org)!
For more information about Haxe, head to the [offical Haxe website](http://haxe.org).
## License
The Haxe project has several licenses, covering different parts of the projects.
* The Haxe compiler is released under the GNU General Public License version 2 or any later version.
* The Haxe libraries are released under a "two-clause" BSD license.
* The Neko runtime is licensed under the GNU Lesser General Public License version 2.1 or any later version.
For the complete Haxe licenses, please see http://haxe.org/foundation/open-source.html or [extra/LICENSE.txt](extra/LICENSE.txt).
## Installing Haxe
The latest stable release is [Haxe 3.2.0-rc2](http://haxe.org/download/version/3.2.0-rc.2/). Pre-built binaries are available for your platform:
* **[Windows installer](http://haxe.org/download/file/3.2.0-rc.2/haxe-3.2.0-rc2-win.exe)**
* **[Windows binaries](http://haxe.org/download/file/3.2.0-rc.2/haxe-3.2.0-rc2-win.zip)**
* **[OSX installer](http://haxe.org/download/file/3.2.0-rc.2/haxe-3.2.0-rc2-osx-installer.pkg)**
* **[OSX binaries](http://haxe.org/download/file/3.2.0-rc.2/haxe-3.2.0-rc2-osx.tar.gz)**
* **[Linux 32-bit binaries](http://haxe.org/download/file/3.2.0-rc.2/haxe-3.2.0-rc2-linux32.tar.gz)**
* **[Linux 64-bit binaries](http://haxe.org/download/file/3.2.0-rc.2/haxe-3.2.0-rc2-linux64.tar.gz)**
Automated development builds are available from [build.haxe.org](http://build.haxe.org).
## Building from source
1. Clone the repository using git. Be sure to initialize and fetch the submodules.
git clone --recursive git://github.com/HaxeFoundation/haxe.git
cd haxe
2. Follow the [documentation on building Haxe for your platform](http://haxe.org/documentation/introduction/building-haxe.html).
## Using Haxe
For information on on using Haxe, consult the [Haxe documentation](http://haxe.org/documentation):
* [Haxe Introduction](http://haxe.org/documentation/introduction), an introduction to the Haxe toolkit
* [The Haxe Manual](http://haxe.org/manual), the reference manual for the Haxe language
* [Haxe API](http://api.haxe.org), documentation for the Haxe standard and native APIs
* [Haxelib](http://lib.haxe.org), a repository of Haxe libraries for a variety of needs
## Community
You can get help and talk with fellow Haxers from around the world via:
* the [official Haxe Google Group](https://groups.google.com/forum/#!forum/haxelang)
* the [Haxe IRC chatroom](http://unic0rn.github.io/tiramisu/haxe), #haxe on chat.freenode.net
## Version compatibility
Haxe | neko
---- | -----
2.* | 1.*
3.0.0 | 2.0.0
3.1.3 | 2.0.0
haxe_3.2.1+dfsg.orig/analyzer.ml 0000664 0001750 0001750 00000142103 12607337712 016504 0 ustar andy andy 0000000 0000000 open Ast
open Type
open Common
open Typecore
let s_expr = s_expr (s_type (print_context()))
let s_expr_pretty = s_expr_pretty "" (s_type (print_context()))
let debug e = print_endline (s_expr e)
let debug_pretty s e = Printf.printf "%s %s\n" s (s_expr_pretty e)
let flag_no_check = "no_check"
let flag_check = "check"
let flag_no_const_propagation = "no_const_propagation"
let flag_const_propagation = "const_propagation"
let flag_no_local_dce = "no_local_dce"
let flag_local_dce = "local_dce"
let flag_ignore = "ignore"
let flag_no_simplification = "no_simplification"
let flag_check_has_effect = "check_has_effect"
let flag_no_check_has_effect = "no_check_has_effect"
let has_analyzer_option meta s =
try
let rec loop ml = match ml with
| (Meta.Analyzer,el,_) :: ml ->
if List.exists (fun (e,p) ->
match e with
| EConst(Ident s2) when s = s2 -> true
| _ -> false
) el then
true
else
loop ml
| _ :: ml ->
loop ml
| [] ->
false
in
loop meta
with Not_found ->
false
let is_ignored meta =
try
let rec loop ml = match ml with
| (Meta.Analyzer,el,_) :: ml ->
if List.exists (fun (e,p) ->
match e with
| EConst(Ident s2) when flag_ignore = s2 -> true
| _ -> false
) el then
true
else
loop ml
| (Meta.HasUntyped,_,_) :: _ ->
true
| _ :: ml ->
loop ml
| [] ->
false
in
loop meta
with Not_found ->
false
let rec get_type_meta t = match t with
| TMono r ->
begin match !r with
| None -> raise Not_found
| Some t -> get_type_meta t
end
| TLazy f ->
get_type_meta (!f())
| TInst(c,_) ->
c.cl_meta
| TEnum(en,_) ->
en.e_meta
| TAbstract(a,_) ->
a.a_meta
| TType(t,_) ->
t.t_meta
| TAnon _ | TFun _ | TDynamic _ ->
raise Not_found
let type_has_analyzer_option t s =
try
has_analyzer_option (get_type_meta t) s
with Not_found ->
false
let is_enum_type t = match follow t with
| TEnum(_) -> true
| _ -> false
let rec awkward_get_enum_index com e = match e.eexpr with
| TArray(e1,{eexpr = TConst(TInt i)}) when com.platform = Js && Int32.to_int i = 1 && is_enum_type e1.etype ->
e1
| TCall({eexpr = TField(e1, FDynamic "__Index")},[]) when com.platform = Cpp && is_enum_type e1.etype ->
e1
| TField(e1,FDynamic "index") when com.platform = Neko && is_enum_type e1.etype ->
e1
| TParenthesis e1 | TCast(e1,None) | TMeta(_,e1) ->
awkward_get_enum_index com e1
| _ ->
raise Not_found
(*
This module simplifies the AST by introducing temporary variables for complex expressions in many places.
In particular, it ensures that no branching can occur in value-places so that we can later insert SSA PHI
nodes without worrying about their placement.
*)
module Simplifier = struct
let mk_block_context com =
let block_el = ref [] in
let push e = block_el := e :: !block_el in
let assign ev e =
let mk_assign e2 = match e2.eexpr with
| TBreak | TContinue | TThrow _ | TReturn _ -> e2
| _ -> mk (TBinop(OpAssign,ev,e2)) e2.etype e2.epos
in
let rec loop e = match e.eexpr with
| TBlock el ->
begin match List.rev el with
| e1 :: el ->
let el = List.rev ((loop e1) :: el) in
{e with eexpr = TBlock el}
| _ ->
mk_assign e
end
| TIf(e1,e2,eo) ->
let e2 = loop e2 in
let eo = match eo with None -> None | Some e3 -> Some (loop e3) in
{e with eexpr = TIf(e1,e2,eo)}
| TSwitch(e1,cases,edef) ->
let cases = List.map (fun (el,e) ->
let e = loop e in
el,e
) cases in
let edef = match edef with None -> None | Some edef -> Some (loop edef) in
{e with eexpr = TSwitch(e1,cases,edef)}
| TTry(e1,catches) ->
let e1 = loop e1 in
let catches = List.map (fun (v,e) ->
let e = loop e in
v,e
) catches in
{e with eexpr = TTry(e1,catches)}
| TParenthesis e1 | TMeta(_,e1) ->
loop e1 (* this is still weird, have to review *)
(* | TBinop(OpAssign,({eexpr = TLocal _} as e1),e2) ->
push e;
mk_assign e1 *)
(* | TBinop(OpAssignOp op,({eexpr = TLocal _} as e1),e2) ->
push e;
mk_assign e1 *)
| _ ->
mk_assign e
in
loop e
in
let declare_temp t eo p =
let v = alloc_var "tmp" t in
v.v_meta <- [Meta.CompilerGenerated,[],p];
let e_v = mk (TLocal v) t p in
let declare e_init =
let e = mk (TVar (v,e_init)) com.basic.tvoid p in
push e;
in
let e_v = match eo with
| None ->
declare None;
e_v
| Some e1 ->
begin match e1.eexpr with
| TThrow _ | TReturn _ | TBreak | TContinue ->
e1
| _ ->
let rec loop e_v e = match e.eexpr with
| TParenthesis e1 ->
loop {e_v with eexpr = TParenthesis e_v} e1
| TMeta(m,e1) ->
loop {e_v with eexpr = TMeta(m,e_v)} e1
| _ ->
e_v,e
in
let e_v',e1 = loop e_v e1 in
let e1 = assign e_v e1 in
begin match e1.eexpr with
| TBinop(OpAssign,{eexpr = TLocal v1},e2) when v == v1 ->
declare (Some e2)
| _ ->
declare None;
push e1
end;
e_v'
end
in
e_v
in
let rec push_block () =
let cur = !block_el in
block_el := [];
fun () ->
let added = !block_el in
block_el := cur;
List.rev added
and block f el =
let close = push_block() in
List.iter (fun e ->
push (f e)
) el;
close()
in
block,declare_temp,fun () -> !block_el
let apply com e =
let block,declare_temp,close_block = mk_block_context com in
let skip_binding ?(allow_tlocal=false) e =
let rec loop e =
match e.eexpr with
| TConst _ | TTypeExpr _ | TFunction _ -> ()
| TLocal _ when allow_tlocal -> ()
| TParenthesis e1 | TCast(e1,None) -> Type.iter loop e
| TField(_,(FStatic(c,cf) | FInstance(c,_,cf))) when has_analyzer_option cf.cf_meta flag_no_simplification || has_analyzer_option c.cl_meta flag_no_simplification -> ()
| TField({eexpr = TLocal _},_) when allow_tlocal -> ()
| TCall({eexpr = TField(_,(FStatic(c,cf) | FInstance(c,_,cf)))},el) when has_analyzer_option cf.cf_meta flag_no_simplification || has_analyzer_option c.cl_meta flag_no_simplification -> ()
| TCall({eexpr = TLocal { v_name = "__cpp__" } },_) -> ()
| TField(_,FEnum _) -> ()
| TField(_,FDynamic _) -> ()
| _ when (try ignore(awkward_get_enum_index com e); true with Not_found -> false) -> ()
| _ -> raise Exit
in
try
loop e;
true
with Exit ->
begin match follow e.etype with
| TAbstract({a_path = [],"Void"},_) -> true
| TInst ({ cl_path = [],"Array" }, _) when com.platform = Cpp -> true
| _ -> false
end
in
let has_unbound = ref false in
let rec loop e = match e.eexpr with
| TCall({eexpr = TLocal v | TField({eexpr = TLocal v},_)},_) | TField({eexpr = TLocal v},_) | TLocal v when Meta.has Meta.Unbound v.v_meta && v.v_name <> "`trace" ->
has_unbound := true;
e
| TBlock el ->
{e with eexpr = TBlock (block loop el)}
| TCall({eexpr = TField(_,(FStatic(c,cf) | FInstance(c,_,cf)))},el) when has_analyzer_option cf.cf_meta flag_no_simplification || has_analyzer_option c.cl_meta flag_no_simplification ->
e
| TField(_,(FStatic(c,cf) | FInstance(c,_,cf))) when has_analyzer_option cf.cf_meta flag_no_simplification || has_analyzer_option c.cl_meta flag_no_simplification ->
e
| TCall(e1,el) ->
let rec is_valid_call_target e = match e.eexpr with
| TFunction _ | TField _ | TLocal _ | TConst (TSuper) ->
true
| TParenthesis e1 | TCast(e1,None) | TMeta(_,e1) ->
is_valid_call_target e1
| _ ->
false
in
let e1 = if is_valid_call_target e1 then
loop e1
else
bind e1
in
let check e t =
if type_has_analyzer_option t flag_no_simplification then e
else bind e
in
let el = match e1.eexpr,follow e1.etype with
| TConst TSuper,_ when com.platform = Java || com.platform = Cs ->
(* they hate you if you mess up the super call *)
el
| _,TFun _ | TConst TSuper,_ ->
Codegen.UnificationCallback.check_call check el e1.etype
| _ ->
(* too dangerous *)
List.map loop el
in
{e with eexpr = TCall(e1,el)}
| TNew(c,tl,el) ->
{e with eexpr = TNew(c,tl,ordered_list el)}
| TArrayDecl el ->
{e with eexpr = TArrayDecl (ordered_list el)}
| TObjectDecl fl ->
let el = ordered_list (List.map snd fl) in
{e with eexpr = TObjectDecl (List.map2 (fun (n,_) e -> n,e) fl el)}
| TBinop(OpBoolAnd | OpBoolOr as op,e1,e2) ->
let e1 = loop e1 in
let e_then = mk (TBlock (block loop [e2])) e2.etype e2.epos in
let e_if,e_else = if op = OpBoolOr then
mk (TUnop(Not,Prefix,e1)) com.basic.tbool e.epos,mk (TConst (TBool(true))) com.basic.tbool e.epos
else
e1,mk (TConst (TBool(false))) com.basic.tbool e.epos
in
loop (mk (TIf(e_if,e_then,Some e_else)) com.basic.tbool e.epos)
| TBinop((OpAssign | OpAssignOp _) as op,{eexpr = TArray(e11,e12)},e2) ->
let e1 = match ordered_list [e11;e12] with
| [e1;e2] ->
{e with eexpr = TArray(e1,e2)}
| _ ->
assert false
in
let e2 = bind e2 in
{e with eexpr = TBinop(op,e1,e2)}
| TBinop((OpAssign | OpAssignOp _) as op,e1,e2) ->
let e2 = bind ~allow_tlocal:true e2 in
let e1 = loop e1 in
{e with eexpr = TBinop(op,e1,e2)}
| TBinop(op,e1,e2) ->
begin match ordered_list [e1;e2] with
| [e1;e2] ->
{e with eexpr = TBinop(op,e1,e2)}
| _ ->
assert false
end
| TArray(e1,e2) ->
begin match ordered_list [e1;e2] with
| [e1;e2] ->
{e with eexpr = TArray(e1,e2)}
| _ ->
assert false
end
| TWhile(e1,e2,flag) when (match e1.eexpr with TConst(TBool true) | TParenthesis {eexpr = TConst(TBool true)} -> false | _ -> true) ->
let p = e.epos in
let e_break = mk TBreak t_dynamic p in
let e_not = mk (TUnop(Not,Prefix,Codegen.mk_parent e1)) e1.etype e1.epos in
let e_if eo = mk (TIf(e_not,e_break,eo)) com.basic.tvoid p in
let rec map_continue e = match e.eexpr with
| TContinue ->
(e_if (Some e))
| TWhile _ | TFor _ ->
e
| _ ->
Type.map_expr map_continue e
in
let e2 = if flag = NormalWhile then e2 else map_continue e2 in
let e_if = e_if None in
let e_if = mk (TMeta((Meta.Custom ":whileCond",[],e_if.epos), e_if)) e_if.etype e_if.epos in
let e_block = if flag = NormalWhile then Type.concat e_if e2 else Type.concat e2 e_if in
let e_true = mk (TConst (TBool true)) com.basic.tbool p in
let e = mk (TWhile(Codegen.mk_parent e_true,e_block,NormalWhile)) e.etype p in
loop e
| TFor(v,e1,e2) ->
let e1 = bind e1 in
let e2 = loop e2 in
{e with eexpr = TFor(v,e1,e2)}
| TIf(e1,e2,eo) ->
let e1 = bind e1 in
let e2 = loop e2 in
let eo = match eo with None -> None | Some e -> Some (loop e) in
{e with eexpr = TIf(e1,e2,eo)}
| TSwitch (e1,cases,eo) ->
let e1 = bind e1 in
let cases = List.map (fun (el,e) ->
let el = List.map loop el in
let e = loop e in
el,e
) cases in
let eo = match eo with None -> None | Some e -> Some (loop e) in
{e with eexpr = TSwitch(e1,cases,eo)}
| TVar(v,Some e1) ->
let e1 = match e1.eexpr with
| TFunction _ -> loop e1
| TArrayDecl [{eexpr = TFunction _}] -> loop e1
| _ -> bind ~allow_tlocal:true e1
in
{e with eexpr = TVar(v,Some e1)}
| TUnop((Neg | NegBits | Not) as op,flag,e1) ->
let e1 = bind e1 in
{e with eexpr = TUnop(op,flag,e1)}
| TField(e1,fa) ->
let e1 = bind ~allow_tlocal:true e1 in
{e with eexpr = TField(e1,fa)}
| TReturn (Some ({eexpr = TThrow _ | TReturn _} as e1)) ->
loop e1 (* this is a bit hackish *)
| TReturn (Some e1) ->
let e1 = bind e1 in
{e with eexpr = TReturn (Some e1)}
| TThrow e1 ->
let e1 = bind e1 in
{e with eexpr = TThrow e1}
| TCast(e1,mto) ->
let e1 = bind ~allow_tlocal:true e1 in
{e with eexpr = TCast(e1,mto)}
| _ ->
Type.map_expr loop e
and bind ?(allow_tlocal=false) e =
let e = loop e in
if skip_binding ~allow_tlocal e then
e
else
declare_temp e.etype (Some e) e.epos
and ordered_list el =
if List.for_all (skip_binding ~allow_tlocal:true) el then
List.map loop el
else
List.map bind el
in
let e = loop e in
!has_unbound,match close_block() with
| [] ->
e
| el ->
mk (TBlock (List.rev (e :: el))) e.etype e.epos
let unapply com e =
let var_map = ref IntMap.empty in
let rec get_assignment_to v e = match e.eexpr with
| TBinop(OpAssign,{eexpr = TLocal v2},e2) when v == v2 -> Some e2
| TBlock [e] -> get_assignment_to v e
| TIf(e1,e2,Some e3) ->
begin match get_assignment_to v e2,get_assignment_to v e3 with
| Some e2,Some e3 -> Some ({e with eexpr = TIf(e1,e2,Some e3)})
| _ -> None
end
| _ -> None
in
let if_or_op e e1 e2 e3 = match e1.eexpr,e3.eexpr with
| TUnop(Not,Prefix,e1),TConst (TBool true) -> {e with eexpr = TBinop(OpBoolOr,e1,e2)}
| _,TConst (TBool false) -> {e with eexpr = TBinop(OpBoolAnd,e1,e2)}
| _ -> {e with eexpr = TIf(e1,e2,Some e3)}
in
let rec loop e = match e.eexpr with
| TBlock el ->
let rec loop2 el = match el with
| e :: el ->
begin match e.eexpr with
| TVar(v,Some e1) when Meta.has Meta.CompilerGenerated v.v_meta ->
if el = [] then
[loop e1]
else begin
var_map := IntMap.add v.v_id (loop e1) !var_map;
loop2 el
end
| TVar(v,None) when not (com.platform = Php) ->
begin match el with
| {eexpr = TBinop(OpAssign,{eexpr = TLocal v2},e2)} :: el when v == v2 ->
let e = {e with eexpr = TVar(v,Some e2)} in
loop2 (e :: el)
| ({eexpr = TIf(e1,e2,Some e3)} as e_if) :: el ->
let e1 = loop e1 in
let e2 = loop e2 in
let e3 = loop e3 in
begin match get_assignment_to v e2,get_assignment_to v e3 with
| Some e2,Some e3 ->
let e_if = if_or_op e_if (loop e1) (loop e2) (loop e3) in
let e = {e with eexpr = TVar(v,Some e_if)} in
loop2 (e :: el)
| _ ->
let e_if = {e_if with eexpr = TIf(e1,e2,Some e3)} in
e :: e_if :: loop2 el
end
| _ ->
let e = loop e in
e :: loop2 el
end
| TReturn (Some e1) when (match follow e1.etype with TAbstract({a_path=[],"Void"},_) -> true | _ -> false) ->
[(loop e1);{e with eexpr = TReturn None}]
| _ ->
let e = loop e in
e :: loop2 el
end
| [] ->
[]
in
let el = loop2 el in
{e with eexpr = TBlock el}
| TLocal v when Meta.has Meta.CompilerGenerated v.v_meta ->
begin try IntMap.find v.v_id !var_map
with Not_found -> e end
| TWhile(e1,e2,flag) ->
let e1 = loop e1 in
let e2 = loop e2 in
let extract_cond e = match e.eexpr with
| TIf({eexpr = TUnop(Not,_,e1)},_,_) -> e1
| TBreak -> raise Exit (* can happen due to optimization, not so easy to deal with because there might be other breaks/continues *)
| _ -> assert false
in
let e1,e2,flag = try
begin match e2.eexpr with
| TBlock el ->
begin match el with
| {eexpr = TMeta((Meta.Custom ":whileCond",_,_),e1)} :: el ->
let e1 = extract_cond e1 in
e1,{e2 with eexpr = TBlock el},NormalWhile
| _ ->
e1,e2,flag
(* issue 3844 *)
(* begin match List.rev el with
| {eexpr = TMeta((Meta.Custom ":whileCond",_,_),e1)} :: el ->
let e1 = extract_cond e1 in
e1,{e2 with eexpr = TBlock (List.rev el)},DoWhile
| _ ->
e1,e2,flag
end *)
end
| _ ->
e1,e2,flag
end with Exit ->
e1,e2,flag
in
{e with eexpr = TWhile(e1,e2,flag)}
| TIf(e1,e2,Some e3) ->
let e1 = loop e1 in
let e2 = loop e2 in
let e3 = loop e3 in
if_or_op e e1 e2 e3
| _ ->
Type.map_expr loop e
in
loop e
end
module Ssa = struct
type var_map = tvar IntMap.t
type condition =
| Equal of tvar * texpr
| NotEqual of tvar * texpr
type node_data = {
nd_pos: pos;
mutable nd_var_map : var_map;
mutable nd_terminates : bool;
}
type join_node = {
mutable branches : node_data list;
}
type ssa_context = {
com : Common.context;
mutable cleanup : (unit -> unit) list;
mutable cur_data : node_data;
mutable var_conds : (condition list) IntMap.t;
mutable loop_stack : (join_node * join_node) list;
mutable exception_stack : join_node list;
mutable block_depth : int;
}
let s_cond = function
| Equal(v,e) -> Printf.sprintf "%s == %s" v.v_name (s_expr_pretty e)
| NotEqual(v,e) -> Printf.sprintf "%s != %s" v.v_name (s_expr_pretty e)
let s_conds conds =
String.concat " && " (List.map s_cond conds)
let mk_loc v p = mk (TLocal v) v.v_type p
let mk_phi =
let v_phi = alloc_var "__ssa_phi__" t_dynamic in
(fun vl p ->
let e = mk (TCall(mk_loc v_phi p,(List.map (fun (v,p) -> mk_loc v p) vl))) t_dynamic p in
e
)
(* TODO: make sure this is conservative *)
let can_throw e =
let rec loop e = match e.eexpr with
| TConst _ | TLocal _ | TTypeExpr _ | TFunction _ | TBlock _ -> ()
| TCall _ | TNew _ | TThrow _ | TCast(_,Some _) -> raise Exit
| _ -> Type.iter loop e
in
try
loop e; false
with Exit ->
true
let mk_join_node() = {
branches = []
}
let mk_node_data p = {
nd_pos = p;
nd_var_map = IntMap.empty;
nd_terminates = false;
}
let add_branch join branch p =
join.branches <- {branch with nd_pos = p} :: join.branches
let branch ctx p =
let old_map = ctx.cur_data.nd_var_map in
let old_term = ctx.cur_data.nd_terminates in
ctx.cur_data.nd_terminates <- false;
(fun join ->
add_branch join ctx.cur_data p;
ctx.cur_data.nd_var_map <- old_map;
ctx.cur_data.nd_terminates <- old_term;
)
let terminate ctx =
ctx.cur_data.nd_terminates <- true
let set_loop_join ctx join_top join_bottom =
ctx.loop_stack <- (join_top,join_bottom) :: ctx.loop_stack;
(fun () ->
ctx.loop_stack <- List.tl ctx.loop_stack
)
let set_exception_join ctx join =
ctx.exception_stack <- join :: ctx.exception_stack;
(fun () ->
ctx.exception_stack <- List.tl ctx.exception_stack;
)
let create_v_extra v =
match v.v_extra with
| Some (_,Some _) ->
()
| Some (tl,None) ->
let e_extra = mk (TObjectDecl []) t_dynamic null_pos in
v.v_extra <- Some (tl,Some e_extra)
| None ->
let e_extra = mk (TObjectDecl []) t_dynamic null_pos in
v.v_extra <- Some ([],Some e_extra)
let set_v_extra_value v s e = match v.v_extra with
| Some (tl, Some {eexpr = TObjectDecl fl}) ->
let rec loop fl = match fl with
| (s',_) :: fl when s' = s ->
(s,e) :: fl
| f1 :: fl ->
f1 :: loop fl
| [] ->
[s,e]
in
let e_extra = mk (TObjectDecl (loop fl)) t_dynamic null_pos in
v.v_extra <- Some (tl, Some e_extra)
| _ ->
assert false
let get_origin_var v = match v.v_extra with
| Some (_,Some {eexpr = TObjectDecl fl}) ->
begin match List.assoc "origin_var" fl with
| {eexpr = TLocal v'} -> v'
| _ -> raise Not_found
end
| _ ->
raise Not_found
let set_origin_var v v_origin p =
let ev = mk_loc v_origin p in
set_v_extra_value v "origin_var" ev
let get_var_value v = match v.v_extra with
| Some (_,Some {eexpr = TObjectDecl fl}) ->
List.assoc "var_value" fl
| _ ->
raise Not_found
let set_var_value v e =
set_v_extra_value v "var_value" e
let get_var_usage_count v = match v.v_extra with
| Some (_,Some {eexpr = TObjectDecl fl}) ->
begin try
begin match List.assoc "usage_count" fl with
| {eexpr = TConst (TInt i32)} -> Int32.to_int i32
| _ -> 0
end
with Not_found ->
0
end
| _ ->
raise Not_found
let set_var_usage_count v i =
let e = mk (TConst (TInt (Int32.of_int i))) t_dynamic null_pos in
set_v_extra_value v "usage_count" e
let declare_var ctx v p =
let old = v.v_extra in
ctx.cleanup <- (fun () ->
v.v_extra <- old
) :: ctx.cleanup;
ctx.cur_data.nd_var_map <- IntMap.add v.v_id v ctx.cur_data.nd_var_map;
v.v_meta <- ((Meta.Custom ":blockDepth",[EConst (Int (string_of_int ctx.block_depth)),p],p)) :: v.v_meta;
v.v_extra <- None;
create_v_extra v;
set_origin_var v v p
let assign_var ctx v e p =
if v.v_capture then
v
else begin
let i = match v.v_extra with
| Some (l,eo) ->
v.v_extra <- Some (("",t_dynamic) :: l,eo);
List.length l + 1
| _ ->
error "Something went wrong" p
in
let v' = alloc_var (Printf.sprintf "%s<%i>" v.v_name i) v.v_type in
create_v_extra v';
v'.v_meta <- [(Meta.Custom ":ssa"),[],p];
set_origin_var v' v p;
ctx.cur_data.nd_var_map <- IntMap.add v.v_id v' ctx.cur_data.nd_var_map;
set_var_value v' e;
v'
end
let get_var ctx v p =
try
IntMap.find v.v_id ctx.cur_data.nd_var_map
with Not_found ->
if not (has_meta Meta.Unbound v.v_meta) then
error (Printf.sprintf "Unbound variable %s" v.v_name) p;
v
let close_join_node ctx node p =
let terminates = ref true in
let branches = List.filter (fun branch ->
if branch.nd_terminates then false
else begin
terminates := false;
true
end
) node.branches in
match branches with
| [] ->
()
| branch :: branches ->
let vars = ref (IntMap.map (fun v -> [v,branch.nd_pos]) branch.nd_var_map) in
let rec handle_branch branch =
IntMap.iter (fun i v ->
try
let vl = IntMap.find i !vars in
if not (List.exists (fun (v',_) -> v == v') vl) then
vars := IntMap.add i ((v,p) :: vl) !vars
with Not_found ->
()
) branch.nd_var_map;
in
List.iter handle_branch branches;
ctx.cur_data.nd_terminates <- !terminates;
IntMap.iter (fun i vl -> match vl with
| [v,p] ->
ctx.cur_data.nd_var_map <- IntMap.add i v ctx.cur_data.nd_var_map;
| (v',_) :: _ ->
let v = get_origin_var v' in
ignore(assign_var ctx v (mk_phi vl p) p)
| _ ->
assert false
) !vars
let invert_cond = function
| Equal(v,e) -> NotEqual(v,e)
| NotEqual(v,e) -> Equal(v,e)
let invert_conds =
List.map invert_cond
let rec eval_cond ctx e = match e.eexpr with
| TBinop(OpNotEq,{eexpr = TLocal v},e1) ->
[NotEqual(v,e1)]
| TBinop(OpEq,{eexpr = TLocal v},e1) ->
[Equal(v,e1)]
| TUnop(Not,_,e1) ->
invert_conds (eval_cond ctx e1)
| TLocal v ->
begin try eval_cond ctx (get_var_value v)
with Not_found -> [] end
| _ ->
[]
let append_cond ctx v cond p =
begin try
let conds = IntMap.find v.v_id ctx.var_conds in
ctx.var_conds <- IntMap.add v.v_id (cond :: conds) ctx.var_conds
with Not_found ->
ctx.var_conds <- IntMap.add v.v_id [cond] ctx.var_conds
end
(* let apply_cond ctx = function
| Equal({v_extra = Some(_,Some {eexpr = TLocal v})} as v0,e1) ->
let v' = assign_var ctx v (mk_loc v0 e1.epos) e1.epos in
append_cond ctx v' (Equal(v',e1)) e1.epos
| NotEqual({v_extra = Some(_,Some {eexpr = TLocal v})} as v0,e1) ->
let v' = assign_var ctx v (mk_loc v0 e1.epos) e1.epos in
append_cond ctx v' (NotEqual(v',e1)) e1.epos
| _ -> ()
let apply_not_null_cond ctx v p =
apply_cond ctx (NotEqual(v,(mk (TConst TNull) t_dynamic p))) *)
let apply com e =
let rec handle_if ctx f econd eif eelse =
let econd = loop ctx econd in
(* let cond = eval_cond ctx econd in *)
let join = mk_join_node() in
let close = branch ctx eif.epos in
(* List.iter (apply_cond ctx) cond; *)
let eif = loop ctx eif in
close join;
let eelse = match eelse with
| None ->
(* let cond = invert_conds cond in *)
(* List.iter (apply_cond ctx) cond; *)
add_branch join ctx.cur_data e.epos;
None
| Some e ->
let close = branch ctx e.epos in
(* let cond = invert_conds cond in *)
(* List.iter (apply_cond ctx) cond; *)
let eelse = loop ctx e in
close join;
Some eelse
in
close_join_node ctx join e.epos;
f econd eif eelse
and handle_loop_body ctx e =
let join_top = mk_join_node() in
let join_bottom = mk_join_node() in
let unset = set_loop_join ctx join_top join_bottom in
let close = branch ctx e.epos in
ignore(loop ctx e); (* TODO: I don't know if this is sane. *)
close join_top;
add_branch join_top ctx.cur_data e.epos;
close_join_node ctx join_top e.epos;
let ebody = loop ctx e in
ctx.cur_data.nd_terminates <- false;
unset();
close_join_node ctx join_bottom e.epos;
ebody
and loop ctx e = match e.eexpr with
(* var declarations *)
| TVar(v,eo) ->
declare_var ctx v e.epos;
let eo = match eo with
| None -> None
| Some e ->
let e = loop ctx e in
set_var_value v e;
Some e
in
{e with eexpr = TVar(v,eo)}
| TFunction tf ->
let close = branch ctx e.epos in
List.iter (fun (v,co) ->
declare_var ctx v e.epos;
(* match co with
| Some TNull when (match v.v_type with TType({t_path=["haxe"],"PosInfos"},_) -> false | _ -> true) -> ()
| _ -> apply_not_null_cond ctx v e.epos *)
) tf.tf_args;
let e' = loop ctx tf.tf_expr in
close (mk_join_node());
{e with eexpr = TFunction {tf with tf_expr = e'}}
(* var modifications *)
| TBinop(OpAssign,({eexpr = TLocal v} as e1),e2) when v.v_name <> "this" ->
let e2 = loop ctx e2 in
let _ = assign_var ctx v e2 e1.epos in
{e with eexpr = TBinop(OpAssign,e1,e2)}
| TBinop(OpAssignOp op,({eexpr = TLocal v} as e1),e2) ->
let e1 = loop ctx e1 in
let e2 = loop ctx e2 in
let e_op = mk (TBinop(op,e1,e2)) e.etype e.epos in
let _ = assign_var ctx v e_op e1.epos in
{e with eexpr = TBinop(OpAssignOp op,e1,e2)}
| TUnop((Increment | Decrement as op),flag,({eexpr = TLocal v} as e1)) ->
let op = match op with Increment -> OpAdd | Decrement -> OpSub | _ -> assert false in
let e_one = mk (TConst (TInt (Int32.of_int 1))) com.basic.tint e.epos in
let e1 = loop ctx e1 in
let e_op = mk (TBinop(op,e1,e_one)) e.etype e.epos in
let _ = assign_var ctx v e_op e1.epos in
e
(* var user *)
| TLocal v ->
let v = get_var ctx v e.epos in
{e with eexpr = TLocal v}
(* control flow *)
| TIf(econd,eif,eelse) ->
let f econd eif eelse = {e with eexpr = TIf(econd,eif,eelse)} in
handle_if ctx f econd eif eelse
| TSwitch(e1,cases,edef) ->
let e1 = loop ctx e1 in
let join = mk_join_node() in
let cases = List.map (fun (el,e) ->
let close = branch ctx e.epos in
let el = List.map (loop ctx) el in
let e = loop ctx e in
close join;
el,e
) cases in
let edef = match edef with
| Some e ->
let close = branch ctx e.epos in
let e = loop ctx e in
close join;
Some e
| None ->
begin match e1.eexpr with
| TMeta((Meta.Exhaustive,_,_),_)
| TParenthesis({eexpr = TMeta((Meta.Exhaustive,_,_),_)}) ->
()
| _ ->
add_branch join ctx.cur_data e.epos;
end;
None
in
close_join_node ctx join e.epos;
let e = {e with eexpr = TSwitch(e1,cases,edef)} in
e
| TWhile(econd,ebody,mode) ->
let econd = loop ctx econd in
let ebody = handle_loop_body ctx ebody in
let e = {e with eexpr = TWhile(econd,ebody,mode)} in
e
| TFor(v,e1,ebody) ->
declare_var ctx v e.epos;
(* apply_not_null_cond ctx v e1.epos; *)
let v' = IntMap.find v.v_id ctx.cur_data.nd_var_map in
let e1 = loop ctx e1 in
let ebody = handle_loop_body ctx ebody in
let e = {e with eexpr = TFor(v',e1,ebody)} in
e
| TTry(e1,catches) ->
let join_ex = mk_join_node() in
let join_bottom = mk_join_node() in
let unset = set_exception_join ctx join_ex in
let e1 = loop ctx e1 in
unset();
add_branch join_bottom ctx.cur_data e.epos;
close_join_node ctx join_ex e.epos;
let catches = List.map (fun (v,e) ->
declare_var ctx v e.epos;
(* apply_not_null_cond ctx v e.epos; *)
let close = branch ctx e.epos in
let e = loop ctx e in
close join_bottom;
v,e
) catches in
close_join_node ctx join_bottom e.epos;
let e = {e with eexpr = TTry(e1,catches)} in
e
| TBreak ->
begin match ctx.loop_stack with
| [] -> error "Break outside loop" e.epos
| (_,join) :: _ -> add_branch join ctx.cur_data e.epos
end;
terminate ctx;
e
| TContinue ->
begin match ctx.loop_stack with
| [] -> error "Continue outside loop" e.epos
| (join,_) :: _ -> add_branch join ctx.cur_data e.epos
end;
terminate ctx;
e
| TThrow e1 ->
let e1 = loop ctx e1 in
begin match ctx.exception_stack with
| join :: _ -> add_branch join ctx.cur_data e.epos
| _ -> ()
end;
terminate ctx;
{e with eexpr = TThrow e1}
| TReturn eo ->
let eo = match eo with None -> None | Some e -> Some (loop ctx e) in
terminate ctx;
{e with eexpr = TReturn eo}
| TBlock el ->
let rec loop2 el = match el with
| [] ->
[]
| e :: el ->
if ctx.cur_data.nd_terminates then begin
(* ctx.com.warning (Printf.sprintf "Unreachable code: %s" (s_expr_pretty e)) e.epos; *)
[]
end else
let e = loop ctx e in
e :: (loop2 el)
in
ctx.block_depth <- ctx.block_depth + 1;
let el = loop2 el in
ctx.block_depth <- ctx.block_depth - 1;
{e with eexpr = TBlock(el)}
| _ ->
begin match ctx.exception_stack with
| join :: _ when can_throw e -> add_branch join ctx.cur_data e.epos
| _ -> ()
end;
Type.map_expr (loop ctx) e
in
let ctx = {
com = com;
cur_data = mk_node_data e.epos;
var_conds = IntMap.empty;
loop_stack = [];
exception_stack = [];
cleanup = [];
block_depth = 0;
} in
let e = loop ctx e in
e,ctx
let unapply com e =
let rec loop e = match e.eexpr with
| TFor(v,e1,e2) when Meta.has (Meta.Custom ":ssa") v.v_meta ->
let v' = get_origin_var v in
let e1 = loop e1 in
let e2 = loop e2 in
{e with eexpr = TFor(v',e1,e2)}
| TLocal v when Meta.has (Meta.Custom ":ssa") v.v_meta ->
let v' = get_origin_var v in
{e with eexpr = TLocal v'}
| TBlock el ->
let rec filter e = match e.eexpr with
| TMeta((Meta.Custom ":ssa",_,_),_) ->
false
| _ ->
true
in
let el = List.filter filter el in
let el = List.map loop el in
{e with eexpr = TBlock el}
| _ ->
Type.map_expr loop e
in
loop e
end
module ConstPropagation = struct
open Ssa
let expr_eq e1 e2 = match e1.eexpr,e2.eexpr with
| TConst ct1, TConst ct2 ->
ct1 = ct2
| _ ->
false
let get_block_depth v = try
let i = match Meta.get (Meta.Custom ":blockDepth") v.v_meta with
| _,[EConst(Int s),_],_ -> int_of_string s
| _ -> raise Not_found
in
i
with Not_found ->
-1
let can_be_inlined com v0 e = type_iseq v0.v_type e.etype && match e.eexpr with
| TConst ct ->
begin match ct with
| TThis | TSuper -> false
(* Some targets don't like seeing null in certain places and won't even compile. We have to detect `if (x != null)
in order for this to work. *)
| TNull when (match com.platform with Php | Cpp -> true | _ -> false) -> false
| _ -> true
end
| TLocal v ->
not (Meta.has Meta.CompilerGenerated v.v_meta) &&
begin try
let v' = Ssa.get_origin_var v in
begin match v'.v_extra with
| Some ([],_) -> get_block_depth v <= get_block_depth v0
| _ -> false
end
with Not_found ->
false
end
| TEnumParameter _ when not (com.platform = Php) ->
Ssa.get_var_usage_count v0 <= 1
| _ ->
false
let semi_awkward_enum_value ssa e i = match e.eexpr with
| TCall({eexpr = TField(_,FEnum _)},el) -> (try List.nth el i with Failure _ -> raise Not_found)
| _ -> raise Not_found
let rec local ssa force v e =
begin try
if v.v_capture then raise Not_found;
if type_has_analyzer_option v.v_type flag_no_const_propagation then raise Not_found;
begin match follow v.v_type with
| TDynamic _ -> raise Not_found
| _ -> ()
end;
let e = Ssa.get_var_value v in
let old = v.v_extra in
v.v_extra <- None;
let e = value ssa force e in
v.v_extra <- old;
Ssa.set_var_value v e;
e
with Not_found ->
e
end
(* force must only be true if the value is not used in the output *)
and value ssa force e = match e.eexpr with
| TUnop((Increment | Decrement),_,_)
| TBinop(OpAssignOp _,_,_)
| TBinop(OpAssign,_,_) ->
e
| TBinop(op,e1,e2) ->
let e1 = value ssa force e1 in
let e2 = value ssa force e2 in
let e = {e with eexpr = TBinop(op,e1,e2)} in
let e' = Optimizer.optimize_binop e op e1 e2 in
if e == e' then
e
else
value ssa force e'
| TUnop(op,flag,e1) ->
let e1 = value ssa force e1 in
let e = {e with eexpr = TUnop(op,flag,e1)} in
let e' = Optimizer.optimize_unop e op flag e1 in
if e == e' then
e
else
value ssa force e'
| TCall (({eexpr = TLocal {v_name = "__ssa_phi__"}} as ephi),el) ->
let el = List.map (value ssa force) el in
begin match el with
| [] -> assert false
| e1 :: el ->
if List.for_all (fun e2 -> expr_eq e1 e2) el then
value ssa force e1
else
{e with eexpr = TCall(ephi, e1 :: el)}
end
| TParenthesis e1 | TMeta(_,e1) ->
value ssa force e1
| TLocal v ->
let e' = local ssa force v e in
if force || can_be_inlined ssa.com v e' then
e'
else
e
| TEnumParameter(e1,ef,i) ->
let ev = value ssa true e1 in
begin try
value ssa force (semi_awkward_enum_value ssa ev i)
with Not_found ->
e
end
| _ ->
e
(* TODO: the name is quite accurate *)
let awkward_get_enum_index ssa e =
let e = awkward_get_enum_index ssa.com e in
let ev = (value ssa true e) in
match ev.eexpr with
| TField(_,FEnum(_,ef)) -> TInt (Int32.of_int ef.ef_index)
| TCall({eexpr = TField(_,FEnum(_,ef))},_) -> TInt (Int32.of_int ef.ef_index)
| _ -> raise Not_found
let apply ssa e =
let rec loop e = match e.eexpr with
| TLocal v when not (Meta.has Meta.Unbound v.v_meta) ->
set_var_usage_count v (get_var_usage_count v + 1);
| _ ->
Type.iter loop e
in
loop e;
let had_function = ref false in
let rec loop e = match e.eexpr with
| TFunction _ when !had_function ->
e
| TFunction tf ->
had_function := true;
{e with eexpr = TFunction {tf with tf_expr = loop tf.tf_expr}}
| TLocal v ->
let e' = local ssa false v e in
if can_be_inlined ssa.com v e' then
e'
else
e
| TCall({eexpr = TField(_,(FStatic(_,cf) | FInstance(_,_,cf) | FAnon cf))},el) when has_analyzer_option cf.cf_meta flag_no_const_propagation ->
e
| TCall(e1,el) ->
let e1 = loop e1 in
let check e t =
if type_has_analyzer_option t flag_no_const_propagation then e
else loop e
in
let el = Codegen.UnificationCallback.check_call check el e1.etype in
{e with eexpr = TCall(e1,el)}
(* | TField(e1,fa) ->
let e1' = loop e1 in
let fa = if e1' != e1 then
begin try quick_field e1'.etype (field_name fa)
with Not_found -> fa end
else
fa
in
{e with eexpr = TField(e1',fa)} *)
| TUnop((Increment | Decrement),_,_) ->
e
| TBinop(OpAssignOp op,e1,e2) ->
let e2 = loop e2 in
{e with eexpr = TBinop(OpAssignOp op,e1,e2)}
| TBinop(OpAssign,({eexpr = TLocal _} as e1),e2) ->
let e2 = loop e2 in
{e with eexpr = TBinop(OpAssign,e1,e2)}
| TBinop(op,e1,e2) ->
let e1 = loop e1 in
let e2 = loop e2 in
let e = {e with eexpr = TBinop(op,e1,e2)} in
let e' = Optimizer.optimize_binop e op e1 e2 in
e'
| TUnop(op,flag,e1) ->
let e1 = loop e1 in
let e = {e with eexpr = TUnop(op,flag,e1)} in
let e' = Optimizer.optimize_unop e op flag e1 in
e'
| TIf(e1,e2,eo) ->
let e1 = loop e1 in
let e2 = loop e2 in
let rec check_const e1 = match e1.eexpr with
| TConst (TBool true) ->
e2
| TConst (TBool false) ->
begin match eo with
| None ->
mk (TConst TNull) t_dynamic e.epos
| Some e ->
loop e
end
| TParenthesis e1 ->
check_const e1
| _ ->
let eo = match eo with None -> None | Some e -> Some (loop e) in
{e with eexpr = TIf(e1,e2,eo)}
in
check_const e1
| TSwitch(e1,cases,edef) ->
let e1 = loop e1 in
let rec check_constant e = match e.eexpr with
| TConst ct -> ct
| TParenthesis e1 | TCast(e1,None) | TMeta(_,e1) -> check_constant e1
| _ -> awkward_get_enum_index ssa e
in
begin try
let ct = check_constant e1 in
begin try
let _,e = List.find (fun (el,_) ->
List.exists (fun e -> match e.eexpr with
| TConst ct2 -> ct = ct2
| _ -> false
) el
) cases in
loop e
with Not_found ->
begin match edef with None -> raise Not_found | Some e -> loop e end
end
with Not_found ->
let cases = List.map (fun (el,e) -> el,loop e) cases in
let edef = match edef with None -> None | Some e -> Some (loop e) in
{e with eexpr = TSwitch(e1,cases,edef)}
end
| _ ->
Type.map_expr loop e
in
loop e
end
module EffectChecker = struct
let run com is_var_expression e =
let has_effect e = match e.eexpr with
| TVar _ -> true
| _ -> Optimizer.has_side_effect e
in
let e = if is_var_expression then
(* var initialization expressions are like assignments, so let's cheat a bit here *)
snd (Simplifier.apply com (Codegen.binop OpAssign (mk (TConst TNull) t_dynamic e.epos) e e.etype e.epos))
else e
in
let rec loop e = match e.eexpr with
| TBlock el ->
List.iter (fun e ->
if not (has_effect e) then com.warning "This expression has no effect" e.epos
) el
| _ ->
Type.iter loop e
in
loop e
end
module Checker = struct
open Ssa
let apply ssa e =
let given_warnings = ref PMap.empty in
let add_pos p =
given_warnings := PMap.add p true !given_warnings
in
let resolve_value v =
let e' = Ssa.get_var_value v in
begin match e'.eexpr with
| TLocal v' when v == v' -> e'
| _ -> e'
end
in
let rec is_null_expr e = match e.eexpr with
| TConst TNull ->
true
| TLocal v ->
(try is_null_expr (resolve_value v) with Not_found -> false)
| _ ->
false
in
let can_be_null v =
not (has_meta Meta.NotNull v.v_meta)
&& try not (List.exists (fun cond -> match cond with
| NotEqual(v',e) when v == v' && is_null_expr e -> true
| _ -> false
) (IntMap.find v.v_id ssa.var_conds)) with Not_found -> true
in
let return b p =
if b then add_pos p;
b
in
let rec can_be_null_expr vstack e =
if PMap.mem e.epos !given_warnings then
false
else match e.eexpr with
| TConst TNull ->
add_pos e.epos;
true
| TBinop((OpAssign | OpAssignOp _),_,e1) ->
can_be_null_expr vstack e1
| TBinop _ | TUnop _ ->
false
| TConst _ | TTypeExpr _ | TNew _ | TObjectDecl _ | TArrayDecl _ | TEnumParameter _ | TFunction _ | TVar _ ->
false
| TFor _ | TWhile _ | TIf _ | TSwitch _ | TTry _ | TReturn _ | TBreak | TContinue | TThrow _ ->
assert false
| TField _ | TBlock _ | TArray _ ->
false (* TODO *)
| TCall ({eexpr = TLocal {v_name = "__ssa_phi__"}},el) ->
List.exists (can_be_null_expr vstack) el
| TLocal v ->
if List.mem v.v_id vstack then
false (* not really, but let's not be a nuisance *)
else
return (can_be_null v && (try can_be_null_expr (v.v_id :: vstack) (resolve_value v) with Not_found -> true)) e.epos;
| TMeta(_,e1) | TParenthesis e1 | TCast(e1,_) ->
can_be_null_expr vstack e1
| TCall(e1,_) ->
begin match follow e1.etype with
| TFun(_,r) -> return (is_explicit_null r) e1.epos
| _ -> false
end
in
let check_null e p =
if can_be_null_expr [] e then begin
ssa.com.warning "Possible null exception" p;
end
in
let rec loop e = match e.eexpr with
| TField(e1,fa) ->
let e1 = loop e1 in
check_null e1 e.epos;
{e with eexpr = TField(e1,fa)}
| TMeta((Meta.Analyzer,[EConst(Ident "testIsNull"),_],_),e1) ->
if not (can_be_null_expr [] e) then error "Analyzer did not find a possible null exception" e.epos;
e
| TMeta((Meta.Analyzer,[EConst(Ident "testIsNotNull"),_],_),e1) ->
if (can_be_null_expr [] e) then error "Analyzer found a possible null exception" e.epos;
e
| _ ->
Type.map_expr loop e
in
loop e;
end
let rec lrev_iter f el = match el with
| e :: el ->
lrev_iter f el;
f e
| [] ->
()
let rev_iter f e = match e.eexpr with
| TConst _
| TLocal _
| TBreak
| TContinue
| TTypeExpr _ ->
()
| TArray (e1,e2)
| TBinop (_,e1,e2)
| TFor (_,e1,e2)
| TWhile (e1,e2,_) ->
f e2;
f e1;
| TThrow e
| TField (e,_)
| TEnumParameter (e,_,_)
| TParenthesis e
| TCast (e,_)
| TUnop (_,_,e)
| TMeta(_,e) ->
f e
| TArrayDecl el
| TNew (_,_,el)
| TBlock el ->
lrev_iter f el
| TObjectDecl fl ->
lrev_iter (fun (_,e) -> f e) fl
| TCall (e,el) ->
f e;
lrev_iter f el
| TVar (v,eo) ->
(match eo with None -> () | Some e -> f e)
| TFunction fu ->
f fu.tf_expr
| TIf (e,e1,e2) ->
(match e2 with None -> () | Some e -> f e);
f e1;
f e;
| TSwitch (e,cases,def) ->
(match def with None -> () | Some e -> f e);
lrev_iter (fun (el,e2) -> lrev_iter f el; f e2) cases;
f e;
| TTry (e,catches) ->
lrev_iter (fun (_,e) -> f e) catches;
f e;
| TReturn eo ->
(match eo with None -> () | Some e -> f e)
module LocalDce = struct
let apply e =
let is_used v = Meta.has Meta.Used v.v_meta || type_has_analyzer_option v.v_type flag_no_local_dce || v.v_capture in
let is_ref_type t = match t with
| TType({t_path = ["cs"],("Ref" | "Out")},_) -> true
| _ -> false
in
let rec use v =
if not (Meta.has Meta.Used v.v_meta) then begin
v.v_meta <- (Meta.Used,[],Ast.null_pos) :: v.v_meta;
try use (Ssa.get_origin_var v) with Not_found -> ()
end
in
let rec has_side_effect e =
let rec loop e =
match e.eexpr with
| TLocal v when Meta.has Meta.CompilerGenerated v.v_meta -> (try loop (Ssa.get_var_value v) with Not_found -> ())
| TBinop((OpAssign | OpAssignOp _),{eexpr = TLocal v},e2) when is_used v || has_side_effect e2 || is_ref_type v.v_type -> raise Exit
| TVar(v,None) when is_used v -> raise Exit
| TVar(v,Some e1) when is_used v || has_side_effect e1 -> raise Exit
| TConst _ | TLocal _ | TTypeExpr _ | TFunction _ -> ()
| TCall ({ eexpr = TField(_,FStatic({ cl_path = ([],"Std") },{ cf_name = "string" })) },args) -> Type.iter loop e
| TCall (({eexpr = TLocal {v_name = "__ssa_phi__"}}),el) -> ()
| TCall ({eexpr = TField(_,FEnum _)},_) -> Type.iter loop e
| TNew _ | TCall _ | TBinop ((OpAssignOp _ | OpAssign),_,_) | TUnop ((Increment|Decrement),_,_) -> raise Exit
| TReturn _ | TBreak | TContinue | TThrow _ | TCast (_,Some _) -> raise Exit
| TFor _ -> raise Exit
| TArray _ | TEnumParameter _ | TCast (_,None) | TBinop _ | TUnop _ | TParenthesis _ | TMeta _ | TWhile _
| TField _ | TIf _ | TTry _ | TSwitch _ | TArrayDecl _ | TBlock _ | TObjectDecl _ | TVar _ -> Type.iter loop e
in
try
loop e;
false
with Exit ->
true
in
let rec collect e = match e.eexpr with
| TLocal v ->
use v
| TVar(v,_) when not (is_used v) ->
(* TODO: this is probably dangerous *)
()
| _ ->
rev_iter collect e
in
let rec loop need_val e =
match e.eexpr with
| TLocal v ->
use v;
e
| TBinop(OpAssign,({eexpr = TLocal v} as e1),e2) ->
let e2 = loop false e2 in
if not (is_used v) && not (is_ref_type v.v_type) then
e2
else
{e with eexpr = TBinop(OpAssign,{e1 with eexpr = TLocal v},e2)}
| TVar(v,Some e1) when not (is_used v) ->
let e1 = if has_side_effect e1 then loop true e1 else e1 in
e1
| TWhile(e1,e2,flag) ->
collect e2;
let e2 = loop false e2 in
let e1 = loop false e1 in
{e with eexpr = TWhile(e1,e2,flag)}
| TFor(v,e1,e2) ->
collect e2;
let e2 = loop false e2 in
let e1 = loop false e1 in
{e with eexpr = TFor(v,e1,e2)}
| TBlock el ->
let rec block el = match el with
| e :: el ->
let el = block el in
if not need_val && not (has_side_effect e) then
el
else begin
let e = loop false e in
e :: el
end
| [] ->
[]
in
{e with eexpr = TBlock (block el)}
| TCall(e1, el) ->
let el = List.rev_map (loop true) (List.rev el) in
let e1 = loop false e1 in
{e with eexpr = TCall(e1,el)}
| TIf(e1,e2,e3) ->
let e3 = match e3 with None -> None | Some e -> Some (loop need_val e) in
let e2 = loop need_val e2 in
let e1 = loop false e1 in
{e with eexpr = TIf(e1,e2,e3)}
| TArrayDecl el ->
let el = List.rev_map (loop true) (List.rev el) in
{e with eexpr = TArrayDecl el}
| TObjectDecl fl ->
let fl = List.rev_map (fun (s,e) -> s,loop true e) (List.rev fl) in
{e with eexpr = TObjectDecl fl}
| _ ->
Type.map_expr (loop false) e
in
loop false e
end
module Config = struct
type analyzer_config = {
analyzer_use : bool;
simplifier_apply : bool;
ssa_apply : bool;
const_propagation : bool;
check : bool;
check_has_effect : bool;
local_dce : bool;
ssa_unapply : bool;
simplifier_unapply : bool;
}
let get_base_config com =
{
analyzer_use = true;
simplifier_apply = true;
ssa_apply = true;
const_propagation = not (Common.raw_defined com "analyzer-no-const-propagation");
check_has_effect = (Common.raw_defined com "analyzer-check-has-effect");
check = not (Common.raw_defined com "analyzer-no-check");
local_dce = not (Common.raw_defined com "analyzer-no-local-dce") && not (Common.defined com Define.As3);
ssa_unapply = not (Common.raw_defined com "analyzer-no-ssa-unapply");
simplifier_unapply = not (Common.raw_defined com "analyzer-no-simplify-unapply");
}
let update_config_from_meta config meta =
List.fold_left (fun config meta -> match meta with
| (Meta.Analyzer,el,_) ->
List.fold_left (fun config e -> match fst e with
| EConst (Ident s) when s = flag_no_check -> { config with check = false}
| EConst (Ident s) when s = flag_check -> { config with check = true}
| EConst (Ident s) when s = flag_no_const_propagation -> { config with const_propagation = false}
| EConst (Ident s) when s = flag_const_propagation -> { config with const_propagation = true}
| EConst (Ident s) when s = flag_no_local_dce -> { config with local_dce = false}
| EConst (Ident s) when s = flag_local_dce -> { config with local_dce = true}
| EConst (Ident s) when s = flag_no_check_has_effect -> { config with check_has_effect = false}
| EConst (Ident s) when s = flag_check_has_effect -> { config with check_has_effect = true}
| _ -> config
) config el
| _ ->
config
) config meta
let get_class_config com c =
let config = get_base_config com in
update_config_from_meta config c.cl_meta
let get_field_config com c cf =
let config = get_class_config com c in
update_config_from_meta config cf.cf_meta
end
module Run = struct
open Config
let run_on_expr com config is_var_expression e =
let do_simplify = (not (Common.defined com Define.NoSimplify) ) && match com.platform with
| Cpp when Common.defined com Define.Cppia -> false
| Cpp | Python -> true
| _ -> false
in
let with_timer s f =
let timer = timer s in
let r = f() in
timer();
r
in
try
let has_unbound,e = if do_simplify || config.analyzer_use then
with_timer "analyzer-simplify-apply" (fun () -> Simplifier.apply com e)
else
false,e
in
let e = if config.analyzer_use && not has_unbound then begin
if config.check_has_effect then EffectChecker.run com is_var_expression e;
let e,ssa = with_timer "analyzer-ssa-apply" (fun () -> Ssa.apply com e) in
let e = if config.const_propagation then with_timer "analyzer-const-propagation" (fun () -> ConstPropagation.apply ssa e) else e in
(* let e = if config.check then with_timer "analyzer-checker" (fun () -> Checker.apply ssa e) else e in *)
let e = if config.local_dce && config.analyzer_use && not has_unbound && not is_var_expression then with_timer "analyzer-local-dce" (fun () -> LocalDce.apply e) else e in
let e = if config.ssa_unapply then with_timer "analyzer-ssa-unapply" (fun () -> Ssa.unapply com e) else e in
List.iter (fun f -> f()) ssa.Ssa.cleanup;
e
end else
e
in
let e = if not do_simplify && not (Common.raw_defined com "analyzer-no-simplify-unapply") then
with_timer "analyzer-simplify-unapply" (fun () -> Simplifier.unapply com e)
else
e
in
e
with Exit ->
e
let run_on_field ctx config cf =
match cf.cf_expr with
| Some e when not (is_ignored cf.cf_meta) && not (Codegen.is_removable_field ctx cf) ->
let config = update_config_from_meta config cf.cf_meta in
let is_var_expression = match cf.cf_kind with
| Var _ -> true
| _ -> false
in
cf.cf_expr <- Some (run_on_expr ctx.com config is_var_expression e);
| _ -> ()
let run_on_class ctx config c =
let config = update_config_from_meta config c.cl_meta in
let process_field cf = run_on_field ctx config cf in
List.iter process_field c.cl_ordered_fields;
List.iter process_field c.cl_ordered_statics;
(match c.cl_constructor with
| None -> ()
| Some f -> process_field f);
(match c.cl_init with
| None -> ()
| Some e ->
(* never optimize init expressions (too messy) *)
c.cl_init <- Some (run_on_expr ctx.com {config with analyzer_use = false} false e))
let run_on_type ctx config t =
match t with
| TClassDecl c when (is_ignored c.cl_meta) -> ()
| TClassDecl c -> run_on_class ctx config c
| TEnumDecl _ -> ()
| TTypeDecl _ -> ()
| TAbstractDecl _ -> ()
let run_on_types ctx types =
let com = ctx.com in
let config = get_base_config com in
List.iter (run_on_type ctx config) types
end
haxe_3.2.1+dfsg.orig/appveyor.yml 0000664 0001750 0001750 00000005323 12607337712 016717 0 ustar andy andy 0000000 0000000 version: "{build}"
platform:
- Win32
environment:
global:
NEKO_ROOT: C:/projects/neko
HAXELIB_ROOT: C:/projects/haxelib
CYG_ARCH: x86
CYG_ROOT: C:/cygwin
CYG_SETUP: C:/cygwin/setup-x86.exe
MINGW_ARCH: i686
WODI: wodi32
ADD_REVISION: 1
OCAMLOPT: ocamlopt.opt
matrix:
- TEST: "neko,cs,java,macro"
- TEST: "cpp"
skip_tags: true
install:
- 'git submodule update --init --recursive'
- cinst 7zip.commandline -y
# Install ocaml using wodi
- appveyor DownloadFile "http://cygwin.com/setup-%CYG_ARCH%.exe" -FileName "%CYG_ROOT%\setup.exe"
- '%CYG_ROOT%/setup.exe -g -q -R "%CYG_ROOT%" -P dos2unix -P diffutils -P cpio -P make -P patch -P mingw64-%MINGW_ARCH%-gcc-core -P mingw64-%MINGW_ARCH%-gcc-g++ > log.txt || type log.txt'
- '%CYG_ROOT%/bin/bash -lc "cygcheck -dc cygwin" > log.txt || type log.txt'
# The archive is a dropbox hosted version of https://github.com/fdopen/godi-repo/issues/7#issuecomment-98480339
- '%CYG_ROOT%/bin/bash -lc "wget -q https://dl.dropboxusercontent.com/u/2661116/wodi/%WODI%.tar.xz -O /tmp/%WODI%.tar.xz" > log.txt || type log.txt'
- '%CYG_ROOT%/bin/bash -lc "cd /tmp && rm -rf %WODI% && tar -xf %WODI%.tar.xz && bash %WODI%/install.sh" > log.txt || type log.txt'
- '%CYG_ROOT%/bin/bash -lc "godi_add godi-zip" > log.txt || type log.txt'
- 'set PATH=%PATH%;%CYG_ROOT%/opt/%WODI%/bin'
# Install neko
- cinst make -y
- 'git clone --recursive https://github.com/HaxeFoundation/neko.git %NEKO_ROOT%'
- 'cd %NEKO_ROOT%'
- set PATH=%PATH%;%NEKO_ROOT%/bin
- msbuild neko_vc10.sln /verbosity:minimal /logger:"C:\Program Files\AppVeyor\BuildAgent\Appveyor.MSBuildLogger.dll" > log.txt || type log.txt
- msbuild libs/libs_vc10.sln /verbosity:minimal /logger:"C:\Program Files\AppVeyor\BuildAgent\Appveyor.MSBuildLogger.dll" > log.txt || type log.txt
- copy /y libs\include\gc\gc.dll bin
- cd %NEKO_ROOT%/src
- neko ../boot/nekoc tools/install.neko
- neko tools/install -nolibs > log.txt || type log.txt
- neko -version
build_script:
- 'cd %APPVEYOR_BUILD_FOLDER%'
- 'set PATH=%PATH%;%APPVEYOR_BUILD_FOLDER%'
- '%CYG_ROOT%/bin/bash -lc "cd \"$OLDPWD\" && make -s -f Makefile.win"'
- '%CYG_ROOT%/bin/bash -lc "cd \"$OLDPWD\" && make -s -f Makefile.win tools"'
- '%CYG_ROOT%/bin/bash -lc "cd \"$OLDPWD\" && make -s -f Makefile.win package_bin"'
- dir %APPVEYOR_BUILD_FOLDER%\out
- cd %APPVEYOR_BUILD_FOLDER%/tests/
- mkdir "%HAXELIB_ROOT%"
- haxelib setup "%HAXELIB_ROOT%"
test_script:
- cd %APPVEYOR_BUILD_FOLDER%/tests/
- haxe -version
- haxe RunCi.hxml
- neko RunCi.n
artifacts:
- path: out/haxe_*.zip
haxe_3.2.1+dfsg.orig/ast.ml 0000664 0001750 0001750 00000041052 12607337712 015447 0 ustar andy andy 0000000 0000000 (*
* Copyright (C)2005-2013 Haxe Foundation
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*)
type pos = {
pfile : string;
pmin : int;
pmax : int;
}
module IntMap = Map.Make(struct type t = int let compare a b = a - b end)
module Meta = struct
type strict_meta =
| Abi
| Abstract
| Access
| Accessor
| Allow
| Analyzer
| Annotation
| ArrayAccess
| Ast
| AutoBuild
| Bind
| Bitmap
| BridgeProperties
| Build
| BuildXml
| Callable
| Class
| ClassCode
| Commutative
| CompilerGenerated
| CoreApi
| CoreType
| CppFileCode
| CppInclude
| CppNamespaceCode
| CsNative
| Dce
| Debug
| Decl
| DefParam
| Delegate
| Depend
| Deprecated
| DirectlyUsed
| DynamicObject
| Enum
| EnumConstructorParam
| Event
| Exhaustive
| Expose
| Extern
| FakeEnum
| File
| Final
| FlatEnum
| Font
| Forward
| From
| FunctionCode
| FunctionTailCode
| Generic
| GenericBuild
| GenericInstance
| Getter
| Hack
| HasUntyped
| HaxeGeneric
| HeaderClassCode
| HeaderCode
| HeaderInclude
| HeaderNamespaceCode
| HxGen
| IfFeature
| Impl
| PythonImport
| ImplicitCast
| Include
| InitPackage
| Internal
| IsVar
| JavaCanonical
| JavaNative
| JsRequire
| Keep
| KeepInit
| KeepSub
| LibType
| Meta
| Macro
| MaybeUsed
| MergeBlock
| MultiType
| Native
| NativeChildren
| NativeGen
| NativeGeneric
| NativeProperty
| NoCompletion
| NoDebug
| NoDoc
| NoExpr
| NoImportGlobal
| NonVirtual
| NoPackageRestrict
| NoPrivateAccess
| NoStack
| NotNull
| NoUsing
| Ns
| Op
| Optional
| Overload
| PrivateAccess
| Property
| Protected
| Public
| PublicFields
| QuotedField
| ReadOnly
| RealPath
| Remove
| Require
| RequiresAssign
(* | Resolve *)
| ReplaceReflection
| Rtti
| Runtime
| RuntimeValue
| SelfCall
| Setter
| SkipCtor
| SkipReflection
| Sound
| SourceFile
| StoredTypedExpr
| Strict
| Struct
| StructAccess
| SuppressWarnings
| This
| Throws
| To
| ToString
| Transient
| ValueUsed
| Volatile
| Unbound
| UnifyMinDynamic
| Unreflective
| Unsafe
| Usage
| Used
| Value
| Void
| Last
(* do not put any custom metadata after Last *)
| Dollar of string
| Custom of string
let has m ml = List.exists (fun (m2,_,_) -> m = m2) ml
let get m ml = List.find (fun (m2,_,_) -> m = m2) ml
let to_string_ref = ref (fun _ -> assert false)
let to_string (m : strict_meta) : string = !to_string_ref m
end
type keyword =
| Function
| Class
| Var
| If
| Else
| While
| Do
| For
| Break
| Continue
| Return
| Extends
| Implements
| Import
| Switch
| Case
| Default
| Static
| Public
| Private
| Try
| Catch
| New
| This
| Throw
| Extern
| Enum
| In
| Interface
| Untyped
| Cast
| Override
| Typedef
| Dynamic
| Package
| Inline
| Using
| Null
| True
| False
| Abstract
| Macro
type binop =
| OpAdd
| OpMult
| OpDiv
| OpSub
| OpAssign
| OpEq
| OpNotEq
| OpGt
| OpGte
| OpLt
| OpLte
| OpAnd
| OpOr
| OpXor
| OpBoolAnd
| OpBoolOr
| OpShl
| OpShr
| OpUShr
| OpMod
| OpAssignOp of binop
| OpInterval
| OpArrow
type unop =
| Increment
| Decrement
| Not
| Neg
| NegBits
type constant =
| Int of string
| Float of string
| String of string
| Ident of string
| Regexp of string * string
type token =
| Eof
| Const of constant
| Kwd of keyword
| Comment of string
| CommentLine of string
| Binop of binop
| Unop of unop
| Semicolon
| Comma
| BrOpen
| BrClose
| BkOpen
| BkClose
| POpen
| PClose
| Dot
| DblDot
| Arrow
| IntInterval of string
| Sharp of string
| Question
| At
| Dollar of string
type unop_flag =
| Prefix
| Postfix
type while_flag =
| NormalWhile
| DoWhile
type type_path = {
tpackage : string list;
tname : string;
tparams : type_param_or_const list;
tsub : string option;
}
and type_param_or_const =
| TPType of complex_type
| TPExpr of expr
and complex_type =
| CTPath of type_path
| CTFunction of complex_type list * complex_type
| CTAnonymous of class_field list
| CTParent of complex_type
| CTExtend of type_path list * class_field list
| CTOptional of complex_type
and func = {
f_params : type_param list;
f_args : (string * bool * complex_type option * expr option) list;
f_type : complex_type option;
f_expr : expr option;
}
and expr_def =
| EConst of constant
| EArray of expr * expr
| EBinop of binop * expr * expr
| EField of expr * string
| EParenthesis of expr
| EObjectDecl of (string * expr) list
| EArrayDecl of expr list
| ECall of expr * expr list
| ENew of type_path * expr list
| EUnop of unop * unop_flag * expr
| EVars of (string * complex_type option * expr option) list
| EFunction of string option * func
| EBlock of expr list
| EFor of expr * expr
| EIn of expr * expr
| EIf of expr * expr * expr option
| EWhile of expr * expr * while_flag
| ESwitch of expr * (expr list * expr option * expr option) list * expr option option
| ETry of expr * (string * complex_type * expr) list
| EReturn of expr option
| EBreak
| EContinue
| EUntyped of expr
| EThrow of expr
| ECast of expr * complex_type option
| EDisplay of expr * bool
| EDisplayNew of type_path
| ETernary of expr * expr * expr
| ECheckType of expr * complex_type
| EMeta of metadata_entry * expr
and expr = expr_def * pos
and type_param = {
tp_name : string;
tp_params : type_param list;
tp_constraints : complex_type list;
}
and documentation = string option
and metadata_entry = (Meta.strict_meta * expr list * pos)
and metadata = metadata_entry list
and access =
| APublic
| APrivate
| AStatic
| AOverride
| ADynamic
| AInline
| AMacro
and class_field_kind =
| FVar of complex_type option * expr option
| FFun of func
| FProp of string * string * complex_type option * expr option
and class_field = {
cff_name : string;
cff_doc : documentation;
cff_pos : pos;
mutable cff_meta : metadata;
mutable cff_access : access list;
mutable cff_kind : class_field_kind;
}
type enum_flag =
| EPrivate
| EExtern
type class_flag =
| HInterface
| HExtern
| HPrivate
| HExtends of type_path
| HImplements of type_path
type abstract_flag =
| APrivAbstract
| AFromType of complex_type
| AToType of complex_type
| AIsType of complex_type
type enum_constructor = {
ec_name : string;
ec_doc : documentation;
ec_meta : metadata;
ec_args : (string * bool * complex_type) list;
ec_pos : pos;
ec_params : type_param list;
ec_type : complex_type option;
}
type ('a,'b) definition = {
d_name : string;
d_doc : documentation;
d_params : type_param list;
d_meta : metadata;
d_flags : 'a list;
d_data : 'b;
}
type import_mode =
| INormal
| IAsName of string
| IAll
type type_def =
| EClass of (class_flag, class_field list) definition
| EEnum of (enum_flag, enum_constructor list) definition
| ETypedef of (enum_flag, complex_type) definition
| EAbstract of (abstract_flag, class_field list) definition
| EImport of (string * pos) list * import_mode
| EUsing of type_path
type type_decl = type_def * pos
type package = string list * type_decl list
exception Error of string * pos
let is_lower_ident i =
let rec loop p =
match String.unsafe_get i p with
| 'a'..'z' -> true
| '_' -> if p + 1 < String.length i then loop (p + 1) else true
| _ -> false
in
loop 0
let pos = snd
let rec is_postfix (e,_) op = match op with
| Increment | Decrement -> true
| Not | Neg | NegBits -> false
let is_prefix = function
| Increment | Decrement -> true
| Not | Neg | NegBits -> true
let base_class_name = snd
let null_pos = { pfile = "?"; pmin = -1; pmax = -1 }
let punion p p2 =
{
pfile = p.pfile;
pmin = min p.pmin p2.pmin;
pmax = max p.pmax p2.pmax;
}
let rec punion_el el = match el with
| [] ->
null_pos
| (_,p) :: [] ->
p
| (_,p) :: el ->
punion p (punion_el el)
let s_type_path (p,s) = match p with [] -> s | _ -> String.concat "." p ^ "." ^ s
let parse_path s =
match List.rev (ExtString.String.nsplit s ".") with
| [] -> failwith "Invalid empty path"
| x :: l -> List.rev l, x
let s_escape ?(hex=true) s =
let b = Buffer.create (String.length s) in
for i = 0 to (String.length s) - 1 do
match s.[i] with
| '\n' -> Buffer.add_string b "\\n"
| '\t' -> Buffer.add_string b "\\t"
| '\r' -> Buffer.add_string b "\\r"
| '"' -> Buffer.add_string b "\\\""
| '\\' -> Buffer.add_string b "\\\\"
| c when int_of_char c < 32 && hex -> Buffer.add_string b (Printf.sprintf "\\x%.2X" (int_of_char c))
| c -> Buffer.add_char b c
done;
Buffer.contents b
let s_constant = function
| Int s -> s
| Float s -> s
| String s -> "\"" ^ s_escape s ^ "\""
| Ident s -> s
| Regexp (r,o) -> "~/" ^ r ^ "/"
let s_access = function
| APublic -> "public"
| APrivate -> "private"
| AStatic -> "static"
| AOverride -> "override"
| ADynamic -> "dynamic"
| AInline -> "inline"
| AMacro -> "macro"
let s_keyword = function
| Function -> "function"
| Class -> "class"
| Static -> "static"
| Var -> "var"
| If -> "if"
| Else -> "else"
| While -> "while"
| Do -> "do"
| For -> "for"
| Break -> "break"
| Return -> "return"
| Continue -> "continue"
| Extends -> "extends"
| Implements -> "implements"
| Import -> "import"
| Switch -> "switch"
| Case -> "case"
| Default -> "default"
| Private -> "private"
| Public -> "public"
| Try -> "try"
| Catch -> "catch"
| New -> "new"
| This -> "this"
| Throw -> "throw"
| Extern -> "extern"
| Enum -> "enum"
| In -> "in"
| Interface -> "interface"
| Untyped -> "untyped"
| Cast -> "cast"
| Override -> "override"
| Typedef -> "typedef"
| Dynamic -> "dynamic"
| Package -> "package"
| Inline -> "inline"
| Using -> "using"
| Null -> "null"
| True -> "true"
| False -> "false"
| Abstract -> "abstract"
| Macro -> "macro"
let rec s_binop = function
| OpAdd -> "+"
| OpMult -> "*"
| OpDiv -> "/"
| OpSub -> "-"
| OpAssign -> "="
| OpEq -> "=="
| OpNotEq -> "!="
| OpGte -> ">="
| OpLte -> "<="
| OpGt -> ">"
| OpLt -> "<"
| OpAnd -> "&"
| OpOr -> "|"
| OpXor -> "^"
| OpBoolAnd -> "&&"
| OpBoolOr -> "||"
| OpShr -> ">>"
| OpUShr -> ">>>"
| OpShl -> "<<"
| OpMod -> "%"
| OpAssignOp op -> s_binop op ^ "="
| OpInterval -> "..."
| OpArrow -> "=>"
let s_unop = function
| Increment -> "++"
| Decrement -> "--"
| Not -> "!"
| Neg -> "-"
| NegBits -> "~"
let s_token = function
| Eof -> ""
| Const c -> s_constant c
| Kwd k -> s_keyword k
| Comment s -> "/*"^s^"*/"
| CommentLine s -> "//"^s
| Binop o -> s_binop o
| Unop o -> s_unop o
| Semicolon -> ";"
| Comma -> ","
| BkOpen -> "["
| BkClose -> "]"
| BrOpen -> "{"
| BrClose -> "}"
| POpen -> "("
| PClose -> ")"
| Dot -> "."
| DblDot -> ":"
| Arrow -> "->"
| IntInterval s -> s ^ "..."
| Sharp s -> "#" ^ s
| Question -> "?"
| At -> "@"
| Dollar v -> "$" ^ v
let unescape s =
let b = Buffer.create 0 in
let rec loop esc i =
if i = String.length s then
()
else
let c = s.[i] in
if esc then begin
let inext = ref (i + 1) in
(match c with
| 'n' -> Buffer.add_char b '\n'
| 'r' -> Buffer.add_char b '\r'
| 't' -> Buffer.add_char b '\t'
| '"' | '\'' | '\\' -> Buffer.add_char b c
| '0'..'3' ->
let c = (try char_of_int (int_of_string ("0o" ^ String.sub s i 3)) with _ -> raise Exit) in
Buffer.add_char b c;
inext := !inext + 2;
| 'x' ->
let c = (try char_of_int (int_of_string ("0x" ^ String.sub s (i+1) 2)) with _ -> raise Exit) in
Buffer.add_char b c;
inext := !inext + 2;
| 'u' ->
let (u, a) =
try
(int_of_string ("0x" ^ String.sub s (i+1) 4), 4)
with _ -> try
assert (s.[i+1] = '{');
let l = String.index_from s (i+3) '}' - (i+2) in
let u = int_of_string ("0x" ^ String.sub s (i+2) l) in
assert (u <= 0x10FFFF);
(u, l+2)
with _ ->
raise Exit
in
let ub = UTF8.Buf.create 0 in
UTF8.Buf.add_char ub (UChar.uchar_of_int u);
Buffer.add_string b (UTF8.Buf.contents ub);
inext := !inext + a;
| _ ->
raise Exit);
loop false !inext;
end else
match c with
| '\\' -> loop true (i + 1)
| c ->
Buffer.add_char b c;
loop false (i + 1)
in
loop false 0;
Buffer.contents b
let map_expr loop (e,p) =
let opt f o =
match o with None -> None | Some v -> Some (f v)
in
let rec tparam = function
| TPType t -> TPType (ctype t)
| TPExpr e -> TPExpr (loop e)
and cfield f =
{ f with cff_kind = (match f.cff_kind with
| FVar (t,e) -> FVar (opt ctype t, opt loop e)
| FFun f -> FFun (func f)
| FProp (get,set,t,e) -> FProp (get,set,opt ctype t,opt loop e))
}
and ctype = function
| CTPath t -> CTPath (tpath t)
| CTFunction (cl,c) -> CTFunction (List.map ctype cl, ctype c)
| CTAnonymous fl -> CTAnonymous (List.map cfield fl)
| CTParent t -> CTParent (ctype t)
| CTExtend (tl,fl) -> CTExtend (List.map tpath tl, List.map cfield fl)
| CTOptional t -> CTOptional (ctype t)
and tparamdecl t =
{ tp_name = t.tp_name; tp_constraints = List.map ctype t.tp_constraints; tp_params = List.map tparamdecl t.tp_params }
and func f =
{
f_params = List.map tparamdecl f.f_params;
f_args = List.map (fun (n,o,t,e) -> n,o,opt ctype t,opt loop e) f.f_args;
f_type = opt ctype f.f_type;
f_expr = opt loop f.f_expr;
}
and tpath t = { t with tparams = List.map tparam t.tparams }
in
let e = (match e with
| EConst _ -> e
| EArray (e1,e2) -> EArray (loop e1, loop e2)
| EBinop (op,e1,e2) -> EBinop (op,loop e1, loop e2)
| EField (e,f) -> EField (loop e, f)
| EParenthesis e -> EParenthesis (loop e)
| EObjectDecl fl -> EObjectDecl (List.map (fun (f,e) -> f,loop e) fl)
| EArrayDecl el -> EArrayDecl (List.map loop el)
| ECall (e,el) -> ECall (loop e, List.map loop el)
| ENew (t,el) -> ENew (tpath t,List.map loop el)
| EUnop (op,f,e) -> EUnop (op,f,loop e)
| EVars vl -> EVars (List.map (fun (n,t,eo) -> n,opt ctype t,opt loop eo) vl)
| EFunction (n,f) -> EFunction (n,func f)
| EBlock el -> EBlock (List.map loop el)
| EFor (e1,e2) -> EFor (loop e1, loop e2)
| EIn (e1,e2) -> EIn (loop e1, loop e2)
| EIf (e,e1,e2) -> EIf (loop e, loop e1, opt loop e2)
| EWhile (econd,e,f) -> EWhile (loop econd, loop e, f)
| ESwitch (e,cases,def) -> ESwitch (loop e, List.map (fun (el,eg,e) -> List.map loop el, opt loop eg, opt loop e) cases, opt (opt loop) def)
| ETry (e, catches) -> ETry (loop e, List.map (fun (n,t,e) -> n,ctype t,loop e) catches)
| EReturn e -> EReturn (opt loop e)
| EBreak -> EBreak
| EContinue -> EContinue
| EUntyped e -> EUntyped (loop e)
| EThrow e -> EThrow (loop e)
| ECast (e,t) -> ECast (loop e,opt ctype t)
| EDisplay (e,f) -> EDisplay (loop e,f)
| EDisplayNew t -> EDisplayNew (tpath t)
| ETernary (e1,e2,e3) -> ETernary (loop e1,loop e2,loop e3)
| ECheckType (e,t) -> ECheckType (loop e, ctype t)
| EMeta (m,e) -> EMeta(m, loop e)
) in
(e,p)
let rec s_expr (e,_) =
match e with
| EConst c -> s_constant c
| EParenthesis e -> "(" ^ (s_expr e) ^ ")"
| EArrayDecl el -> "[" ^ (String.concat "," (List.map s_expr el)) ^ "]"
| EObjectDecl fl -> "{" ^ (String.concat "," (List.map (fun (n,e) -> n ^ ":" ^ (s_expr e)) fl)) ^ "}"
| EBinop (op,e1,e2) -> s_expr e1 ^ s_binop op ^ s_expr e2
| ECall (e,el) -> s_expr e ^ "(" ^ (String.concat ", " (List.map s_expr el)) ^ ")"
| EField (e,f) -> s_expr e ^ "." ^ f
| _ -> "'???'"
let get_value_meta meta =
try
begin match Meta.get Meta.Value meta with
| (_,[EObjectDecl values,_],_) -> List.fold_left (fun acc (s,e) -> PMap.add s e acc) PMap.empty values
| _ -> raise Not_found
end
with Not_found ->
PMap.empty
let rec string_list_of_expr_path_raise (e,p) =
match e with
| EConst (Ident i) -> [i]
| EField (e,f) -> f :: string_list_of_expr_path_raise e
| _ -> raise Exit
haxe_3.2.1+dfsg.orig/codegen.ml 0000664 0001750 0001750 00000202262 12607337712 016266 0 ustar andy andy 0000000 0000000 (*
* Copyright (C)2005-2013 Haxe Foundation
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*)
open Ast
open Type
open Common
open Typecore
(* -------------------------------------------------------------------------- *)
(* TOOLS *)
let field e name t p =
mk (TField (e,try quick_field e.etype name with Not_found -> assert false)) t p
let fcall e name el ret p =
let ft = tfun (List.map (fun e -> e.etype) el) ret in
mk (TCall (field e name ft p,el)) ret p
let mk_parent e =
mk (TParenthesis e) e.etype e.epos
let string com str p =
mk (TConst (TString str)) com.basic.tstring p
let binop op a b t p =
mk (TBinop (op,a,b)) t p
let index com e index t p =
mk (TArray (e,mk (TConst (TInt (Int32.of_int index))) com.basic.tint p)) t p
let maybe_cast e t =
try
type_eq EqDoNotFollowNull e.etype t;
e
with
Unify_error _ -> mk (TCast(e,None)) t e.epos
let type_constant com c p =
let t = com.basic in
match c with
| Int s ->
if String.length s > 10 && String.sub s 0 2 = "0x" then error "Invalid hexadecimal integer" p;
(try mk (TConst (TInt (Int32.of_string s))) t.tint p
with _ -> mk (TConst (TFloat s)) t.tfloat p)
| Float f -> mk (TConst (TFloat f)) t.tfloat p
| String s -> mk (TConst (TString s)) t.tstring p
| Ident "true" -> mk (TConst (TBool true)) t.tbool p
| Ident "false" -> mk (TConst (TBool false)) t.tbool p
| Ident "null" -> mk (TConst TNull) (t.tnull (mk_mono())) p
| Ident t -> error ("Invalid constant : " ^ t) p
| Regexp _ -> error "Invalid constant" p
let rec type_constant_value com (e,p) =
match e with
| EConst c ->
type_constant com c p
| EParenthesis e ->
type_constant_value com e
| EObjectDecl el ->
mk (TObjectDecl (List.map (fun (n,e) -> n, type_constant_value com e) el)) (TAnon { a_fields = PMap.empty; a_status = ref Closed }) p
| EArrayDecl el ->
mk (TArrayDecl (List.map (type_constant_value com) el)) (com.basic.tarray t_dynamic) p
| _ ->
error "Constant value expected" p
let rec has_properties c =
List.exists (fun f ->
match f.cf_kind with
| Var { v_read = AccCall } -> true
| Var { v_write = AccCall } -> true
| _ when Meta.has Meta.Accessor f.cf_meta -> true
| _ -> false
) c.cl_ordered_fields || (match c.cl_super with Some (c,_) -> has_properties c | _ -> false)
let get_properties fields =
List.fold_left (fun acc f ->
if Meta.has Meta.Accessor f.cf_meta then
(f.cf_name, f.cf_name) :: acc
else
let acc = (match f.cf_kind with
| Var { v_read = AccCall } -> ("get_" ^ f.cf_name , "get_" ^ f.cf_name) :: acc
| _ -> acc) in
match f.cf_kind with
| Var { v_write = AccCall } -> ("set_" ^ f.cf_name , "set_" ^ f.cf_name) :: acc
| _ -> acc
) [] fields
let add_property_field com c =
let p = c.cl_pos in
let props = get_properties (c.cl_ordered_statics @ c.cl_ordered_fields) in
match props with
| [] -> ()
| _ ->
let fields,values = List.fold_left (fun (fields,values) (n,v) ->
let cf = mk_field n com.basic.tstring p in
PMap.add n cf fields,(n, string com v p) :: values
) (PMap.empty,[]) props in
let t = mk_anon fields in
let e = mk (TObjectDecl values) t p in
let cf = mk_field "__properties__" t p in
cf.cf_expr <- Some e;
c.cl_statics <- PMap.add cf.cf_name cf c.cl_statics;
c.cl_ordered_statics <- cf :: c.cl_ordered_statics
let is_removable_field ctx f =
Meta.has Meta.Extern f.cf_meta || Meta.has Meta.Generic f.cf_meta
|| (match f.cf_kind with
| Var {v_read = AccRequire (s,_)} -> true
| Method MethMacro -> not ctx.in_macro
| _ -> false)
let escape_res_name name allow_dirs =
ExtString.String.replace_chars (fun chr ->
if (chr >= 'a' && chr <= 'z') || (chr >= 'A' && chr <= 'Z') || (chr >= '0' && chr <= '9') || chr = '_' || chr = '.' then
Char.escaped chr
else if chr = '/' && allow_dirs then
"/"
else
"-x" ^ (string_of_int (Char.code chr))) name
(* -------------------------------------------------------------------------- *)
(* REMOTING PROXYS *)
let extend_remoting ctx c t p async prot =
if c.cl_super <> None then error "Cannot extend several classes" p;
(* remove forbidden packages *)
let rules = ctx.com.package_rules in
ctx.com.package_rules <- PMap.foldi (fun key r acc -> match r with Forbidden -> acc | _ -> PMap.add key r acc) rules PMap.empty;
(* parse module *)
let path = (t.tpackage,t.tname) in
let new_name = (if async then "Async_" else "Remoting_") ^ t.tname in
(* check if the proxy already exists *)
let t = (try
Typeload.load_type_def ctx p { tpackage = fst path; tname = new_name; tparams = []; tsub = None }
with
Error (Module_not_found _,p2) when p == p2 ->
(* build it *)
Common.log ctx.com ("Building proxy for " ^ s_type_path path);
let file, decls = (try
Typeload.parse_module ctx path p
with
| Not_found -> ctx.com.package_rules <- rules; error ("Could not load proxy module " ^ s_type_path path ^ (if fst path = [] then " (try using absolute path)" else "")) p
| e -> ctx.com.package_rules <- rules; raise e) in
ctx.com.package_rules <- rules;
let base_fields = [
{ cff_name = "__cnx"; cff_pos = p; cff_doc = None; cff_meta = []; cff_access = []; cff_kind = FVar (Some (CTPath { tpackage = ["haxe";"remoting"]; tname = if async then "AsyncConnection" else "Connection"; tparams = []; tsub = None }),None) };
{ cff_name = "new"; cff_pos = p; cff_doc = None; cff_meta = []; cff_access = [APublic]; cff_kind = FFun { f_args = ["c",false,None,None]; f_type = None; f_expr = Some (EBinop (OpAssign,(EConst (Ident "__cnx"),p),(EConst (Ident "c"),p)),p); f_params = [] } };
] in
let tvoid = CTPath { tpackage = []; tname = "Void"; tparams = []; tsub = None } in
let build_field is_public acc f =
if f.cff_name = "new" then
acc
else match f.cff_kind with
| FFun fd when (is_public || List.mem APublic f.cff_access) && not (List.mem AStatic f.cff_access) ->
if List.exists (fun (_,_,t,_) -> t = None) fd.f_args then error ("Field " ^ f.cff_name ^ " type is not complete and cannot be used by RemotingProxy") p;
let eargs = [EArrayDecl (List.map (fun (a,_,_,_) -> (EConst (Ident a),p)) fd.f_args),p] in
let ftype = (match fd.f_type with Some (CTPath { tpackage = []; tname = "Void" }) -> None | _ -> fd.f_type) in
let fargs, eargs = if async then match ftype with
| Some tret -> fd.f_args @ ["__callb",true,Some (CTFunction ([tret],tvoid)),None], eargs @ [EConst (Ident "__callb"),p]
| _ -> fd.f_args, eargs @ [EConst (Ident "null"),p]
else
fd.f_args, eargs
in
let id = (EConst (String f.cff_name), p) in
let id = if prot then id else ECall ((EConst (Ident "__unprotect__"),p),[id]),p in
let expr = ECall (
(EField (
(ECall ((EField ((EConst (Ident "__cnx"),p),"resolve"),p),[id]),p),
"call")
,p),eargs),p
in
let expr = if async || ftype = None then expr else (EReturn (Some expr),p) in
let fd = {
f_params = fd.f_params;
f_args = fargs;
f_type = if async then None else ftype;
f_expr = Some (EBlock [expr],p);
} in
{ cff_name = f.cff_name; cff_pos = p; cff_doc = None; cff_meta = []; cff_access = [APublic]; cff_kind = FFun fd } :: acc
| _ -> acc
in
let decls = List.map (fun d ->
match d with
| EClass c, p when c.d_name = t.tname ->
let is_public = List.mem HExtern c.d_flags || List.mem HInterface c.d_flags in
let fields = List.rev (List.fold_left (build_field is_public) base_fields c.d_data) in
(EClass { c with d_flags = []; d_name = new_name; d_data = fields },p)
| _ -> d
) decls in
let m = Typeload.type_module ctx (t.tpackage,new_name) file decls p in
add_dependency ctx.m.curmod m;
try
List.find (fun tdecl -> snd (t_path tdecl) = new_name) m.m_types
with Not_found ->
error ("Module " ^ s_type_path path ^ " does not define type " ^ t.tname) p
) in
match t with
| TClassDecl c2 when c2.cl_params = [] -> ignore(c2.cl_build()); c.cl_super <- Some (c2,[]);
| _ -> error "Remoting proxy must be a class without parameters" p
(* -------------------------------------------------------------------------- *)
(* HAXE.RTTI.GENERIC *)
exception Generic_Exception of string * Ast.pos
type generic_context = {
ctx : typer;
subst : (t * t) list;
name : string;
p : pos;
mutable mg : module_def option;
}
let make_generic ctx ps pt p =
let rec loop l1 l2 =
match l1, l2 with
| [] , [] -> []
| (x,TLazy f) :: l1, _ -> loop ((x,(!f)()) :: l1) l2
| (_,t1) :: l1 , t2 :: l2 -> (t1,t2) :: loop l1 l2
| _ -> assert false
in
let name =
String.concat "_" (List.map2 (fun (s,_) t ->
let s_type_path_underscore (p,s) = match p with [] -> s | _ -> String.concat "_" p ^ "_" ^ s in
let rec loop top t = match follow t with
| TInst(c,tl) -> (s_type_path_underscore c.cl_path) ^ (loop_tl tl)
| TEnum(en,tl) -> (s_type_path_underscore en.e_path) ^ (loop_tl tl)
| TAbstract(a,tl) -> (s_type_path_underscore a.a_path) ^ (loop_tl tl)
| _ when not top -> "_" (* allow unknown/incompatible types as type parameters to retain old behavior *)
| TMono _ -> raise (Generic_Exception (("Could not determine type for parameter " ^ s), p))
| t -> raise (Generic_Exception (("Type parameter must be a class or enum instance (found " ^ (s_type (print_context()) t) ^ ")"), p))
and loop_tl tl = match tl with
| [] -> ""
| tl -> "_" ^ String.concat "_" (List.map (loop false) tl)
in
loop true t
) ps pt)
in
{
ctx = ctx;
subst = loop ps pt;
name = name;
p = p;
mg = None;
}
let rec generic_substitute_type gctx t =
match t with
| TInst ({ cl_kind = KGeneric } as c2,tl2) ->
(* maybe loop, or generate cascading generics *)
let _, _, f = gctx.ctx.g.do_build_instance gctx.ctx (TClassDecl c2) gctx.p in
let t = f (List.map (generic_substitute_type gctx) tl2) in
(match follow t,gctx.mg with TInst(c,_), Some m -> add_dependency m c.cl_module | _ -> ());
t
| _ ->
try
generic_substitute_type gctx (List.assq t gctx.subst)
with Not_found ->
Type.map (generic_substitute_type gctx) t
let generic_substitute_expr gctx e =
let vars = Hashtbl.create 0 in
let build_var v =
try
Hashtbl.find vars v.v_id
with Not_found ->
let v2 = alloc_var v.v_name (generic_substitute_type gctx v.v_type) in
v2.v_meta <- v.v_meta;
Hashtbl.add vars v.v_id v2;
v2
in
let rec build_expr e =
match e.eexpr with
| TField(e1, FInstance({cl_kind = KGeneric} as c,tl,cf)) ->
let _, _, f = gctx.ctx.g.do_build_instance gctx.ctx (TClassDecl c) gctx.p in
let t = f (List.map (generic_substitute_type gctx) tl) in
build_expr {e with eexpr = TField(e1,quick_field t cf.cf_name)}
| _ ->
map_expr_type build_expr (generic_substitute_type gctx) build_var e
in
build_expr e
let has_ctor_constraint c = match c.cl_kind with
| KTypeParameter tl ->
List.exists (fun t -> match follow t with
| TAnon a when PMap.mem "new" a.a_fields -> true
| _ -> false
) tl;
| _ -> false
let get_short_name =
let i = ref (-1) in
(fun () ->
incr i;
Printf.sprintf "Hx___short___hx_type_%i" !i
)
let rec build_generic ctx c p tl =
let pack = fst c.cl_path in
let recurse = ref false in
let rec check_recursive t =
match follow t with
| TInst (c2,tl) ->
(match c2.cl_kind with
| KTypeParameter tl ->
if not (Typeload.is_generic_parameter ctx c2) && has_ctor_constraint c2 then
error "Type parameters with a constructor cannot be used non-generically" p;
recurse := true
| _ -> ());
List.iter check_recursive tl;
| _ ->
()
in
List.iter check_recursive tl;
if !recurse then begin
TInst (c,tl) (* build a normal instance *)
end else begin
let gctx = make_generic ctx c.cl_params tl p in
let name = (snd c.cl_path) ^ "_" ^ gctx.name in
try
Typeload.load_instance ctx { tpackage = pack; tname = name; tparams = []; tsub = None } p false
with Error(Module_not_found path,_) when path = (pack,name) ->
let m = (try Hashtbl.find ctx.g.modules (Hashtbl.find ctx.g.types_module c.cl_path) with Not_found -> assert false) in
let ctx = { ctx with m = { ctx.m with module_types = m.m_types @ ctx.m.module_types } } in
ignore(c.cl_build()); (* make sure the super class is already setup *)
let mg = {
m_id = alloc_mid();
m_path = (pack,name);
m_types = [];
m_extra = module_extra (s_type_path (pack,name)) m.m_extra.m_sign 0. MFake;
} in
gctx.mg <- Some mg;
let cg = mk_class mg (pack,name) c.cl_pos in
mg.m_types <- [TClassDecl cg];
Hashtbl.add ctx.g.modules mg.m_path mg;
add_dependency mg m;
add_dependency ctx.m.curmod mg;
(* ensure that type parameters are set in dependencies *)
let dep_stack = ref [] in
let rec loop t =
if not (List.memq t !dep_stack) then begin
dep_stack := t :: !dep_stack;
match t with
| TInst (c,tl) -> add_dep c.cl_module tl
| TEnum (e,tl) -> add_dep e.e_module tl
| TType (t,tl) -> add_dep t.t_module tl
| TAbstract (a,tl) -> add_dep a.a_module tl
| TMono r ->
(match !r with
| None -> ()
| Some t -> loop t)
| TLazy f ->
loop ((!f)());
| TDynamic t2 ->
if t == t2 then () else loop t2
| TAnon a ->
PMap.iter (fun _ f -> loop f.cf_type) a.a_fields
| TFun (args,ret) ->
List.iter (fun (_,_,t) -> loop t) args;
loop ret
end
and add_dep m tl =
add_dependency mg m;
List.iter loop tl
in
List.iter loop tl;
let build_field cf_old =
let cf_new = {cf_old with cf_pos = cf_old.cf_pos} in (* copy *)
let f () =
let t = generic_substitute_type gctx cf_old.cf_type in
ignore (follow t);
begin try (match cf_old.cf_expr with
| None ->
begin match cf_old.cf_kind with
| Method _ when not c.cl_interface && not c.cl_extern ->
display_error ctx (Printf.sprintf "Field %s has no expression (possible typing order issue)" cf_new.cf_name) cf_new.cf_pos;
display_error ctx (Printf.sprintf "While building %s" (s_type_path cg.cl_path)) p;
| _ ->
()
end
| Some e ->
cf_new.cf_expr <- Some (generic_substitute_expr gctx e)
) with Unify_error l ->
error (error_msg (Unify l)) cf_new.cf_pos
end;
t
in
let r = exc_protect ctx (fun r ->
let t = mk_mono() in
r := (fun() -> t);
unify_raise ctx (f()) t p;
t
) "build_generic" in
delay ctx PForce (fun() -> ignore ((!r)()));
cf_new.cf_type <- TLazy r;
cf_new
in
if c.cl_init <> None || c.cl_dynamic <> None then error "This class can't be generic" p;
List.iter (fun cf -> match cf.cf_kind with
| Method MethMacro when not ctx.in_macro -> ()
| _ -> error "A generic class can't have static fields" cf.cf_pos
) c.cl_ordered_statics;
cg.cl_super <- (match c.cl_super with
| None -> None
| Some (cs,pl) ->
let find_class subst =
let rec loop subst = match subst with
| (TInst(c,[]),t) :: subst when c == cs -> t
| _ :: subst -> loop subst
| [] -> raise Not_found
in
try
if pl <> [] then raise Not_found;
let t = loop subst in
(* extended type parameter: concrete type must have a constructor, but generic base class must not have one *)
begin match follow t,c.cl_constructor with
| TInst(cs,_),None ->
ignore(cs.cl_build());
begin match cs.cl_constructor with
| None -> error ("Cannot use " ^ (s_type_path cs.cl_path) ^ " as type parameter because it is extended and has no constructor") p
| _ -> ()
end;
| _,Some cf -> error "Generics extending type parameters cannot have constructors" cf.cf_pos
| _ -> ()
end;
t
with Not_found ->
apply_params c.cl_params tl (TInst(cs,pl))
in
let ts = follow (find_class gctx.subst) in
let cs,pl = Typeload.check_extends ctx c ts p in
match cs.cl_kind with
| KGeneric ->
(match build_generic ctx cs p pl with
| TInst (cs,pl) -> Some (cs,pl)
| _ -> assert false)
| _ -> Some(cs,pl)
);
Typeload.add_constructor ctx cg false p;
cg.cl_kind <- KGenericInstance (c,tl);
cg.cl_meta <- (Meta.NoDoc,[],p) :: cg.cl_meta;
cg.cl_interface <- c.cl_interface;
cg.cl_constructor <- (match cg.cl_constructor, c.cl_constructor, c.cl_super with
| _, Some cf, _ -> Some (build_field cf)
| Some ctor, _, _ -> Some ctor
| None, None, None -> None
| _ -> error "Please define a constructor for this class in order to use it as generic" c.cl_pos
);
cg.cl_implements <- List.map (fun (i,tl) ->
(match follow (generic_substitute_type gctx (TInst (i, List.map (generic_substitute_type gctx) tl))) with
| TInst (i,tl) -> i, tl
| _ -> assert false)
) c.cl_implements;
cg.cl_ordered_fields <- List.map (fun f ->
let f = build_field f in
cg.cl_fields <- PMap.add f.cf_name f cg.cl_fields;
f
) c.cl_ordered_fields;
(* In rare cases the class name can become too long, so let's shorten it (issue #3090). *)
if String.length (snd cg.cl_path) > 254 then begin
let n = get_short_name () in
cg.cl_meta <- (Meta.Native,[EConst(String (n)),p],p) :: cg.cl_meta;
end;
TInst (cg,[])
end
(* -------------------------------------------------------------------------- *)
(* HAXE.XML.PROXY *)
let extend_xml_proxy ctx c t file p =
let t = Typeload.load_complex_type ctx p t in
let file = (try Common.find_file ctx.com file with Not_found -> file) in
add_dependency c.cl_module (create_fake_module ctx file);
let used = ref PMap.empty in
let print_results() =
PMap.iter (fun id used ->
if not used then ctx.com.warning (id ^ " is not used") p;
) (!used)
in
let check_used = Common.defined ctx.com Define.CheckXmlProxy in
if check_used then ctx.g.hook_generate <- print_results :: ctx.g.hook_generate;
try
let rec loop = function
| Xml.Element (_,attrs,childs) ->
(try
let id = List.assoc "id" attrs in
if PMap.mem id c.cl_fields then error ("Duplicate id " ^ id) p;
let t = if not check_used then t else begin
used := PMap.add id false (!used);
let ft() = used := PMap.add id true (!used); t in
TLazy (ref ft)
end in
let f = {
cf_name = id;
cf_type = t;
cf_public = true;
cf_pos = p;
cf_doc = None;
cf_meta = no_meta;
cf_kind = Var { v_read = AccResolve; v_write = AccNo };
cf_params = [];
cf_expr = None;
cf_overloads = [];
} in
c.cl_fields <- PMap.add id f c.cl_fields;
with
Not_found -> ());
List.iter loop childs;
| Xml.PCData _ -> ()
in
loop (Xml.parse_file file)
with
| Xml.Error e -> error ("XML error " ^ Xml.error e) p
| Xml.File_not_found f -> error ("XML File not found : " ^ f) p
(* -------------------------------------------------------------------------- *)
(* BUILD META DATA OBJECT *)
let build_metadata com t =
let api = com.basic in
let p, meta, fields, statics = (match t with
| TClassDecl c ->
let fields = List.map (fun f -> f.cf_name,f.cf_meta) (c.cl_ordered_fields @ (match c.cl_constructor with None -> [] | Some f -> [{ f with cf_name = "_" }])) in
let statics = List.map (fun f -> f.cf_name,f.cf_meta) c.cl_ordered_statics in
(c.cl_pos, ["",c.cl_meta],fields,statics)
| TEnumDecl e ->
(e.e_pos, ["",e.e_meta],List.map (fun n -> n, (PMap.find n e.e_constrs).ef_meta) e.e_names, [])
| TTypeDecl t ->
(t.t_pos, ["",t.t_meta],(match follow t.t_type with TAnon a -> PMap.fold (fun f acc -> (f.cf_name,f.cf_meta) :: acc) a.a_fields [] | _ -> []),[])
| TAbstractDecl a ->
(a.a_pos, ["",a.a_meta],[],[])
) in
let filter l =
let l = List.map (fun (n,ml) -> n, ExtList.List.filter_map (fun (m,el,p) -> match m with Meta.Custom s when String.length s > 0 && s.[0] <> ':' -> Some (s,el,p) | _ -> None) ml) l in
List.filter (fun (_,ml) -> ml <> []) l
in
let meta, fields, statics = filter meta, filter fields, filter statics in
let make_meta_field ml =
let h = Hashtbl.create 0 in
mk (TObjectDecl (List.map (fun (f,el,p) ->
if Hashtbl.mem h f then error ("Duplicate metadata '" ^ f ^ "'") p;
Hashtbl.add h f ();
f, mk (match el with [] -> TConst TNull | _ -> TArrayDecl (List.map (type_constant_value com) el)) (api.tarray t_dynamic) p
) ml)) t_dynamic p
in
let make_meta l =
mk (TObjectDecl (List.map (fun (f,ml) -> f,make_meta_field ml) l)) t_dynamic p
in
if meta = [] && fields = [] && statics = [] then
None
else
let meta_obj = [] in
let meta_obj = (if fields = [] then meta_obj else ("fields",make_meta fields) :: meta_obj) in
let meta_obj = (if statics = [] then meta_obj else ("statics",make_meta statics) :: meta_obj) in
let meta_obj = (try ("obj", make_meta_field (List.assoc "" meta)) :: meta_obj with Not_found -> meta_obj) in
Some (mk (TObjectDecl meta_obj) t_dynamic p)
(* -------------------------------------------------------------------------- *)
(* MACRO TYPE *)
let get_macro_path ctx e args p =
let rec loop e =
match fst e with
| EField (e,f) -> f :: loop e
| EConst (Ident i) -> [i]
| _ -> error "Invalid macro call" p
in
let path = match e with
| (EConst(Ident i)),_ ->
let path = try
if not (PMap.mem i ctx.curclass.cl_statics) then raise Not_found;
ctx.curclass.cl_path
with Not_found -> try
(t_infos (fst (PMap.find i ctx.m.module_globals))).mt_path
with Not_found ->
error "Invalid macro call" p
in
i :: (snd path) :: (fst path)
| _ ->
loop e
in
(match path with
| meth :: cl :: path -> (List.rev path,cl), meth, args
| _ -> error "Invalid macro call" p)
let build_macro_type ctx pl p =
let path, field, args = (match pl with
| [TInst ({ cl_kind = KExpr (ECall (e,args),_) },_)]
| [TInst ({ cl_kind = KExpr (EArrayDecl [ECall (e,args),_],_) },_)] ->
get_macro_path ctx e args p
| _ ->
error "MacroType requires a single expression call parameter" p
) in
let old = ctx.ret in
let t = (match ctx.g.do_macro ctx MMacroType path field args p with
| None -> mk_mono()
| Some _ -> ctx.ret
) in
ctx.ret <- old;
t
let build_macro_build ctx c pl cfl p =
let path, field, args = match Meta.get Meta.GenericBuild c.cl_meta with
| _,[ECall(e,args),_],_ -> get_macro_path ctx e args p
| _ -> error "genericBuild requires a single expression call parameter" p
in
let old = ctx.ret,ctx.g.get_build_infos in
ctx.g.get_build_infos <- (fun() -> Some (TClassDecl c, pl, cfl));
let t = (match ctx.g.do_macro ctx MMacroType path field args p with
| None -> mk_mono()
| Some _ -> ctx.ret
) in
ctx.ret <- fst old;
ctx.g.get_build_infos <- snd old;
t
(* -------------------------------------------------------------------------- *)
(* API EVENTS *)
let build_instance ctx mtype p =
match mtype with
| TClassDecl c ->
if ctx.pass > PBuildClass then ignore(c.cl_build());
let build f s =
let r = exc_protect ctx (fun r ->
let t = mk_mono() in
r := (fun() -> t);
unify_raise ctx (f()) t p;
t
) s in
delay ctx PForce (fun() -> ignore ((!r)()));
TLazy r
in
let ft = (fun pl ->
match c.cl_kind with
| KGeneric ->
build (fun () -> build_generic ctx c p pl) "build_generic"
| KMacroType ->
build (fun () -> build_macro_type ctx pl p) "macro_type"
| KGenericBuild cfl ->
build (fun () -> build_macro_build ctx c pl cfl p) "generic_build"
| _ ->
TInst (c,pl)
) in
c.cl_params , c.cl_path , ft
| TEnumDecl e ->
e.e_params , e.e_path , (fun t -> TEnum (e,t))
| TTypeDecl t ->
t.t_params , t.t_path , (fun tl -> TType(t,tl))
| TAbstractDecl a ->
a.a_params, a.a_path, (fun tl -> TAbstract(a,tl))
let on_inherit ctx c p h =
match h with
| HExtends { tpackage = ["haxe";"remoting"]; tname = "Proxy"; tparams = [TPType(CTPath t)] } ->
extend_remoting ctx c t p false true;
false
| HExtends { tpackage = ["haxe";"remoting"]; tname = "AsyncProxy"; tparams = [TPType(CTPath t)] } ->
extend_remoting ctx c t p true true;
false
| HExtends { tpackage = ["haxe";"xml"]; tname = "Proxy"; tparams = [TPExpr(EConst (String file),p);TPType t] } ->
extend_xml_proxy ctx c t file p;
true
| _ ->
true
(* -------------------------------------------------------------------------- *)
(* ABSTRACT CASTS *)
module AbstractCast = struct
let cast_stack = ref []
let make_static_call ctx c cf a pl args t p =
make_static_call ctx c cf (apply_params a.a_params pl) args t p
let do_check_cast ctx tleft eright p =
let recurse cf f =
if cf == ctx.curfield || List.mem cf !cast_stack then error "Recursive implicit cast" p;
cast_stack := cf :: !cast_stack;
let r = f() in
cast_stack := List.tl !cast_stack;
r
in
let find a tl f =
let tcf,cf = f() in
if (Meta.has Meta.MultiType a.a_meta) then
mk_cast eright tleft p
else match a.a_impl with
| Some c -> recurse cf (fun () ->
let ret = make_static_call ctx c cf a tl [eright] tleft p in
{ ret with eexpr = TMeta( (Meta.ImplicitCast,[],ret.epos), ret) }
)
| None -> assert false
in
if type_iseq tleft eright.etype then
eright
else begin
let rec loop tleft tright = match follow tleft,follow tright with
| TAbstract(a1,tl1),TAbstract(a2,tl2) ->
begin try find a2 tl2 (fun () -> Abstract.find_to a2 tl2 tleft)
with Not_found -> try find a1 tl1 (fun () -> Abstract.find_from a1 tl1 eright.etype tleft)
with Not_found -> raise Not_found
end
| TAbstract(a,tl),_ ->
begin try find a tl (fun () -> Abstract.find_from a tl eright.etype tleft)
with Not_found ->
let rec loop2 tcl = match tcl with
| tc :: tcl ->
if not (type_iseq tc tleft) then loop (apply_params a.a_params tl tc) tright
else loop2 tcl
| [] -> raise Not_found
in
loop2 a.a_from
end
| _,TAbstract(a,tl) ->
begin try find a tl (fun () -> Abstract.find_to a tl tleft)
with Not_found ->
let rec loop2 tcl = match tcl with
| tc :: tcl ->
if not (type_iseq tc tright) then loop tleft (apply_params a.a_params tl tc)
else loop2 tcl
| [] -> raise Not_found
in
loop2 a.a_to
end
| _ ->
raise Not_found
in
loop tleft eright.etype
end
let cast_or_unify_raise ctx tleft eright p =
try
if ctx.com.display <> DMNone then raise Not_found;
do_check_cast ctx tleft eright p
with Not_found ->
unify_raise ctx eright.etype tleft p;
eright
let cast_or_unify ctx tleft eright p =
try
cast_or_unify_raise ctx tleft eright p
with Error (Unify _ as err,_) ->
if not ctx.untyped then display_error ctx (error_msg err) p;
eright
let find_array_access_raise ctx a pl e1 e2o p =
let is_set = e2o <> None in
let ta = apply_params a.a_params pl a.a_this in
let rec loop cfl = match cfl with
| [] -> raise Not_found
| cf :: cfl when not (Ast.Meta.has Ast.Meta.ArrayAccess cf.cf_meta) ->
loop cfl
| cf :: cfl ->
let monos = List.map (fun _ -> mk_mono()) cf.cf_params in
let map t = apply_params a.a_params pl (apply_params cf.cf_params monos t) in
let check_constraints () =
List.iter2 (fun m (name,t) -> match follow t with
| TInst ({ cl_kind = KTypeParameter constr },_) when constr <> [] ->
List.iter (fun tc -> match follow m with TMono _ -> raise (Unify_error []) | _ -> Type.unify m (map tc) ) constr
| _ -> ()
) monos cf.cf_params;
in
match follow (map cf.cf_type) with
| TFun([(_,_,tab);(_,_,ta1);(_,_,ta2)],r) as tf when is_set ->
begin try
Type.unify tab ta;
let e1 = cast_or_unify_raise ctx ta1 e1 p in
let e2o = match e2o with None -> None | Some e2 -> Some (cast_or_unify_raise ctx ta2 e2 p) in
check_constraints();
cf,tf,r,e1,e2o
with Unify_error _ | Error (Unify _,_) ->
loop cfl
end
| TFun([(_,_,tab);(_,_,ta1)],r) as tf when not is_set ->
begin try
Type.unify tab ta;
let e1 = cast_or_unify_raise ctx ta1 e1 p in
check_constraints();
cf,tf,r,e1,None
with Unify_error _ | Error (Unify _,_) ->
loop cfl
end
| _ -> loop cfl
in
loop a.a_array
let find_array_access ctx a tl e1 e2o p =
try find_array_access_raise ctx a tl e1 e2o p
with Not_found -> match e2o with
| None ->
error (Printf.sprintf "No @:arrayAccess function accepts argument of %s" (s_type (print_context()) e1.etype)) p
| Some e2 ->
error (Printf.sprintf "No @:arrayAccess function accepts arguments of %s and %s" (s_type (print_context()) e1.etype) (s_type (print_context()) e2.etype)) p
let find_multitype_specialization com a pl p =
let m = mk_mono() in
let tl = match Meta.get Meta.MultiType a.a_meta with
| _,[],_ -> pl
| _,el,_ ->
let relevant = Hashtbl.create 0 in
List.iter (fun e -> match fst e with
| EConst(Ident s) -> Hashtbl.replace relevant s true
| _ -> error "Type parameter expected" (pos e)
) el;
let tl = List.map2 (fun (n,_) t -> if Hashtbl.mem relevant n || not (has_mono t) then t else t_dynamic) a.a_params pl in
if com.platform = Js && a.a_path = ([],"Map") then begin match tl with
| t1 :: _ ->
let rec loop stack t =
if List.exists (fun t2 -> fast_eq t t2) stack then
t
else begin
let stack = t :: stack in
match follow t with
| TAbstract ({ a_path = [],"Class" },_) ->
error (Printf.sprintf "Cannot use %s as key type to Map because Class is not comparable" (s_type (print_context()) t1)) p;
| TEnum(en,tl) ->
PMap.iter (fun _ ef -> ignore(loop stack ef.ef_type)) en.e_constrs;
Type.map (loop stack) t
| t ->
Type.map (loop stack) t
end
in
ignore(loop [] t1)
| _ -> assert false
end;
tl
in
let _,cf =
try
Abstract.find_to a tl m
with Not_found ->
let at = apply_params a.a_params pl a.a_this in
let st = s_type (print_context()) at in
if has_mono at then
error ("Type parameters of multi type abstracts must be known (for " ^ st ^ ")") p
else
error ("Abstract " ^ (s_type_path a.a_path) ^ " has no @:to function that accepts " ^ st) p;
in
cf, follow m
let handle_abstract_casts ctx e =
let rec loop ctx e = match e.eexpr with
| TNew({cl_kind = KAbstractImpl a} as c,pl,el) ->
(* 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 e = make_static_call ctx c cf a pl ((mk (TConst TNull) (TAbstract(a,pl)) e.epos) :: el) m e.epos in
{e with etype = m}
| TCall({eexpr = TField(_,FStatic({cl_path=[],"Std"},{cf_name = "string"}))},[e1]) when (match follow e1.etype with TAbstract({a_impl = Some _},_) -> true | _ -> false) ->
begin match follow e1.etype with
| TAbstract({a_impl = Some c} as a,tl) ->
begin try
let cf = PMap.find "toString" c.cl_statics in
make_static_call ctx c cf a tl [e1] ctx.t.tstring e.epos
with Not_found ->
e
end
| _ ->
assert false
end
| TCall(e1, el) ->
begin try
let rec find_abstract e = match follow e.etype,e.eexpr with
| TAbstract(a,pl),_ when Meta.has Meta.MultiType a.a_meta -> a,pl,e
| _,TCast(e1,None) -> find_abstract e1
| _ -> raise Not_found
in
let rec find_field e1 =
match e1.eexpr with
| TCast(e2,None) ->
{e1 with eexpr = TCast(find_field e2,None)}
| TField(e2,fa) ->
let a,pl,e2 = find_abstract e2 in
let m = Abstract.get_underlying_type a pl in
let fname = field_name fa in
let el = List.map (loop ctx) el in
begin try
let fa = quick_field m fname in
let get_fun_type t = match follow t with
| TFun(_,tr) as tf -> tf,tr
| _ -> raise Not_found
in
let tf,tr = match fa with
| FStatic(_,cf) -> get_fun_type cf.cf_type
| FInstance(c,tl,cf) -> get_fun_type (apply_params c.cl_params tl cf.cf_type)
| FAnon cf -> get_fun_type cf.cf_type
| _ -> raise Not_found
in
let ef = mk (TField({e2 with etype = m},fa)) tf e2.epos in
let ecall = make_call ctx ef el tr e.epos in
if not (type_iseq ecall.etype e.etype) then
mk (TCast(ecall,None)) e.etype e.epos
else
ecall
with Not_found ->
(* quick_field raises Not_found if m is an abstract, we have to replicate the 'using' call here *)
match follow m with
| TAbstract({a_impl = Some c} as a,pl) ->
let cf = PMap.find fname c.cl_statics in
make_static_call ctx c cf a pl (e2 :: el) e.etype e.epos
| _ -> raise Not_found
end
| _ ->
raise Not_found
in
find_field e1
with Not_found ->
Type.map_expr (loop ctx) e
end
| _ ->
Type.map_expr (loop ctx) e
in
loop ctx e
end
module PatternMatchConversion = struct
type cctx = {
ctx : typer;
mutable eval_stack : ((tvar * pos) * texpr) list list;
dt_lookup : dt array;
}
let is_declared cctx v =
let rec loop sl = match sl with
| stack :: sl ->
List.exists (fun ((v2,_),_) -> v == v2) stack || loop sl
| [] ->
false
in
loop cctx.eval_stack
let group_cases cases =
let dt_eq dt1 dt2 = match dt1,dt2 with
| DTGoto i1, DTGoto i2 when i1 = i2 -> true
(* TODO equal bindings *)
| _ -> false
in
match List.rev cases with
| [] -> []
| [con,dt] -> [[con],dt]
| (con,dt) :: cases ->
let tmp,ldt,cases = List.fold_left (fun (tmp,ldt,acc) (con,dt) ->
if dt_eq dt ldt then
(con :: tmp,dt,acc)
else
([con],dt,(tmp,ldt) :: acc)
) ([con],dt,[]) cases in
match tmp with
| [] -> cases
| tmp -> ((tmp,ldt) :: cases)
let replace_locals e =
let v_known = ref IntMap.empty in
let copy v =
let v' = alloc_var v.v_name v.v_type in
v_known := IntMap.add v.v_id v' !v_known;
v'
in
let rec loop e = match e.eexpr with
| TVar(v,e1) ->
let v' = copy v in
let e1 = match e1 with None -> None | Some e -> Some (loop e) in
{e with eexpr = TVar(v',e1)}
| TFor(v,e1,e2) ->
let v' = copy v in
let e1 = loop e1 in
let e2 = loop e2 in
{e with eexpr = TFor(v',e1,e2)}
| TTry(e1,catches) ->
let e1 = loop e1 in
let catches = List.map (fun (v,e) ->
let v' = copy v in
let e = loop e in
v',e
) catches in
{e with eexpr = TTry(e1,catches)}
| TLocal v ->
let v' = try IntMap.find v.v_id !v_known with Not_found -> v in
{e with eexpr = TLocal v'}
| _ ->
Type.map_expr loop e
in
loop e
let rec convert_dt cctx dt =
match dt with
| DTBind (bl,dt) ->
cctx.eval_stack <- bl :: cctx.eval_stack;
let e = convert_dt cctx dt in
cctx.eval_stack <- List.tl cctx.eval_stack;
let vl,el = List.fold_left (fun (vl,el) ((v,p),e) ->
if is_declared cctx v then
vl, (mk (TBinop(OpAssign,mk (TLocal v) v.v_type p,e)) e.etype e.epos) :: el
else
((v,p,Some e) :: vl), el
) ([],[e]) bl in
let el_v = List.map (fun (v,p,eo) -> mk (TVar (v,eo)) cctx.ctx.t.tvoid p) vl in
mk (TBlock (el_v @ el)) e.etype e.epos
| DTGoto i ->
convert_dt cctx (cctx.dt_lookup.(i))
| DTExpr e ->
e
| DTGuard(e,dt1,dt2) ->
let ethen = convert_dt cctx dt1 in
mk (TIf(e,ethen,match dt2 with None -> None | Some dt -> Some (convert_dt cctx dt))) ethen.etype (punion e.epos ethen.epos)
| DTSwitch({eexpr = TMeta((Meta.Exhaustive,_,_),_)},[_,dt],None) ->
convert_dt cctx dt
| DTSwitch(e_st,cl,dto) ->
let def = match dto with None -> None | Some dt -> Some (convert_dt cctx dt) in
let cases = group_cases cl in
let cases = List.map (fun (cl,dt) ->
let e = convert_dt cctx dt in
(* The macro interpreter does not care about unique locals and
we don't run the analyzer on the output, so let's save some
time here (issue #3937) *)
let e = if cctx.ctx.in_macro then e else replace_locals e in
cl,e
) cases in
mk (TSwitch(e_st,cases,def)) (mk_mono()) e_st.epos
let to_typed_ast ctx dt p =
let first = dt.dt_dt_lookup.(dt.dt_first) in
let cctx = {
ctx = ctx;
dt_lookup = dt.dt_dt_lookup;
eval_stack = [];
} in
let e = convert_dt cctx first in
let e = { e with epos = p; etype = dt.dt_type} in
if dt.dt_var_init = [] then
e
else begin
let el_v = List.map (fun (v,eo) -> mk (TVar (v,eo)) cctx.ctx.t.tvoid p) dt.dt_var_init in
mk (TBlock (el_v @ [e])) dt.dt_type e.epos
end
end
(* -------------------------------------------------------------------------- *)
(* USAGE *)
let detect_usage com =
let usage = ref [] in
List.iter (fun t -> match t with
| TClassDecl c ->
let check_constructor c p =
try
let _,cf = get_constructor (fun cf -> cf.cf_type) c in
if Meta.has Meta.Usage cf.cf_meta then
usage := p :: !usage;
with Not_found ->
()
in
let rec expr e = match e.eexpr with
| TField(_,FEnum(_,ef)) when Meta.has Meta.Usage ef.ef_meta ->
let p = {e.epos with pmin = e.epos.pmax - (String.length ef.ef_name)} in
usage := p :: !usage;
Type.iter expr e
| TField(_,(FAnon cf | FInstance (_,_,cf) | FStatic (_,cf) | FClosure (_,cf))) when Meta.has Meta.Usage cf.cf_meta ->
let p = {e.epos with pmin = e.epos.pmax - (String.length cf.cf_name)} in
usage := p :: !usage;
Type.iter expr e
| TLocal v when Meta.has Meta.Usage v.v_meta ->
usage := e.epos :: !usage
| TVar (v,_) when com.display = DMPosition && Meta.has Meta.Usage v.v_meta ->
raise (Typecore.DisplayPosition [e.epos])
| TFunction tf when com.display = DMPosition && List.exists (fun (v,_) -> Meta.has Meta.Usage v.v_meta) tf.tf_args ->
raise (Typecore.DisplayPosition [e.epos])
| TTypeExpr mt when (Meta.has Meta.Usage (t_infos mt).mt_meta) ->
usage := e.epos :: !usage
| TNew (c,_,_) ->
check_constructor c e.epos;
Type.iter expr e;
| TCall({eexpr = TConst TSuper},_) ->
begin match c.cl_super with
| Some (c,_) ->
check_constructor c e.epos
| _ ->
()
end
| _ -> Type.iter expr e
in
let field cf = ignore(follow cf.cf_type); match cf.cf_expr with None -> () | Some e -> expr e in
(match c.cl_constructor with None -> () | Some cf -> field cf);
(match c.cl_init with None -> () | Some e -> expr e);
List.iter field c.cl_ordered_statics;
List.iter field c.cl_ordered_fields;
| _ -> ()
) com.types;
let usage = List.sort (fun p1 p2 ->
let c = compare p1.pfile p2.pfile in
if c <> 0 then c else compare p1.pmin p2.pmin
) !usage in
raise (Typecore.DisplayPosition usage)
let update_cache_dependencies com =
let rec check_t m t = match t with
| TInst(c,tl) ->
add_dependency m c.cl_module;
List.iter (check_t m) tl;
| TEnum(en,tl) ->
add_dependency m en.e_module;
List.iter (check_t m) tl;
| TType(t,tl) ->
add_dependency m t.t_module;
List.iter (check_t m) tl;
| TAbstract(a,tl) ->
add_dependency m a.a_module;
List.iter (check_t m) tl;
| TFun(targs,tret) ->
List.iter (fun (_,_,t) -> check_t m t) targs;
check_t m tret;
| TAnon an ->
PMap.iter (fun _ cf -> check_field m cf) an.a_fields
| TMono r ->
(match !r with
| Some t -> check_t m t
| _ -> ())
| TLazy f ->
check_t m (!f())
| TDynamic t ->
if t == t_dynamic then
()
else
check_t m t
and check_field m cf =
check_t m cf.cf_type
in
List.iter (fun t -> match t with
| TClassDecl c ->
List.iter (check_field c.cl_module) c.cl_ordered_statics;
List.iter (check_field c.cl_module) c.cl_ordered_fields;
(match c.cl_constructor with None -> () | Some cf -> check_field c.cl_module cf);
| _ ->
()
) com.types
(* -------------------------------------------------------------------------- *)
(* STACK MANAGEMENT EMULATION *)
type stack_context = {
stack_var : string;
stack_exc_var : string;
stack_pos_var : string;
stack_pos : pos;
stack_expr : texpr;
stack_pop : texpr;
stack_save_pos : texpr;
stack_restore : texpr list;
stack_push : tclass -> string -> texpr;
stack_return : texpr -> texpr;
}
let stack_context_init com stack_var exc_var pos_var tmp_var use_add p =
let t = com.basic in
let st = t.tarray t.tstring in
let stack_var = alloc_var stack_var st in
let exc_var = alloc_var exc_var st in
let pos_var = alloc_var pos_var t.tint in
let stack_e = mk (TLocal stack_var) st p in
let exc_e = mk (TLocal exc_var) st p in
let stack_pop = fcall stack_e "pop" [] t.tstring p in
let stack_push c m =
fcall stack_e "push" [
if use_add then
binop OpAdd (string com (s_type_path c.cl_path ^ "::") p) (string com m p) t.tstring p
else
string com (s_type_path c.cl_path ^ "::" ^ m) p
] t.tvoid p
in
let stack_return e =
let tmp = alloc_var tmp_var e.etype in
mk (TBlock [
mk (TVar (tmp, Some e)) t.tvoid e.epos;
stack_pop;
mk (TReturn (Some (mk (TLocal tmp) e.etype e.epos))) e.etype e.epos
]) e.etype e.epos
in
{
stack_var = stack_var.v_name;
stack_exc_var = exc_var.v_name;
stack_pos_var = pos_var.v_name;
stack_pos = p;
stack_expr = stack_e;
stack_pop = stack_pop;
stack_save_pos = mk (TVar (pos_var, Some (field stack_e "length" t.tint p))) t.tvoid p;
stack_push = stack_push;
stack_return = stack_return;
stack_restore = [
binop OpAssign exc_e (mk (TArrayDecl []) st p) st p;
mk (TWhile (
mk_parent (binop OpGte (field stack_e "length" t.tint p) (mk (TLocal pos_var) t.tint p) t.tbool p),
fcall exc_e "unshift" [fcall stack_e "pop" [] t.tstring p] t.tvoid p,
NormalWhile
)) t.tvoid p;
fcall stack_e "push" [index com exc_e 0 t.tstring p] t.tvoid p
];
}
let stack_init com use_add =
stack_context_init com "$s" "$e" "$spos" "$tmp" use_add null_pos
let rec stack_block_loop ctx e =
match e.eexpr with
| TFunction _ ->
e
| TReturn None | TReturn (Some { eexpr = TConst _ }) | TReturn (Some { eexpr = TLocal _ }) ->
mk (TBlock [
ctx.stack_pop;
e;
]) e.etype e.epos
| TReturn (Some e) ->
ctx.stack_return (stack_block_loop ctx e)
| TTry (v,cases) ->
let v = stack_block_loop ctx v in
let cases = List.map (fun (v,e) ->
let e = stack_block_loop ctx e in
let e = (match (mk_block e).eexpr with
| TBlock l -> mk (TBlock (ctx.stack_restore @ l)) e.etype e.epos
| _ -> assert false
) in
v , e
) cases in
mk (TTry (v,cases)) e.etype e.epos
| _ ->
map_expr (stack_block_loop ctx) e
let stack_block ctx c m e =
match (mk_block e).eexpr with
| TBlock l ->
mk (TBlock (
ctx.stack_push c m ::
ctx.stack_save_pos ::
List.map (stack_block_loop ctx) l
@ [ctx.stack_pop]
)) e.etype e.epos
| _ ->
assert false
(* -------------------------------------------------------------------------- *)
(* FIX OVERRIDES *)
(*
on some platforms which doesn't support type parameters, we must have the
exact same type for overriden/implemented function as the original one
*)
let rec find_field com c f =
try
(match c.cl_super with
| None ->
raise Not_found
| Some ( {cl_path = (["cpp"],"FastIterator")}, _ ) ->
raise Not_found (* This is a strongly typed 'extern' and the usual rules don't apply *)
| Some (c,_) ->
find_field com c f)
with Not_found -> try
if com.platform = Cpp then (* Cpp uses delegation for interfaces *)
raise Not_found;
let rec loop = function
| [] ->
raise Not_found
| (c,_) :: l ->
try
find_field com c f
with
Not_found -> loop l
in
loop c.cl_implements
with Not_found ->
let f = PMap.find f.cf_name c.cl_fields in
(match f.cf_kind with Var { v_read = AccRequire _ } -> raise Not_found | _ -> ());
f
let fix_override com c f fd =
let f2 = (try Some (find_field com c f) with Not_found -> None) in
match f2,fd with
| Some (f2), Some(fd) ->
let targs, tret = (match follow f2.cf_type with TFun (args,ret) -> args, ret | _ -> assert false) in
let changed_args = ref [] in
let prefix = "_tmp_" in
let nargs = List.map2 (fun ((v,ct) as cur) (_,_,t2) ->
try
type_eq EqStrict (monomorphs c.cl_params (monomorphs f.cf_params v.v_type)) t2;
(* Flash generates type parameters with a single constraint as that constraint type, so we
have to detect this case and change the variable (issue #2712). *)
begin match follow v.v_type with
| TInst({cl_kind = KTypeParameter [tc]} as cp,_) when com.platform = Flash ->
if List.mem_assoc (snd cp.cl_path) c.cl_params then raise (Unify_error [])
| _ ->
()
end;
cur
with Unify_error _ ->
let v2 = alloc_var (prefix ^ v.v_name) t2 in
changed_args := (v,v2) :: !changed_args;
v2,ct
) fd.tf_args targs in
let fd2 = {
tf_args = nargs;
tf_type = tret;
tf_expr = (match List.rev !changed_args with
| [] -> fd.tf_expr
| args ->
let e = fd.tf_expr in
let el = (match e.eexpr with TBlock el -> el | _ -> [e]) in
let p = (match el with [] -> e.epos | e :: _ -> e.epos) in
let el_v = List.map (fun (v,v2) ->
mk (TVar (v,Some (mk (TCast (mk (TLocal v2) v2.v_type p,None)) v.v_type p))) com.basic.tvoid p
) args in
{ e with eexpr = TBlock (el_v @ el) }
);
} in
(* as3 does not allow wider visibility, so the base method has to be made public *)
if Common.defined com Define.As3 && f.cf_public then f2.cf_public <- true;
let targs = List.map (fun(v,c) -> (v.v_name, Option.is_some c, v.v_type)) nargs in
let fde = (match f.cf_expr with None -> assert false | Some e -> e) in
f.cf_expr <- Some { fde with eexpr = TFunction fd2 };
f.cf_type <- TFun(targs,tret);
| Some(f2), None when c.cl_interface ->
let targs, tret = (match follow f2.cf_type with TFun (args,ret) -> args, ret | _ -> assert false) in
f.cf_type <- TFun(targs,tret)
| _ ->
()
let fix_overrides com t =
match t with
| TClassDecl c ->
(* overrides can be removed from interfaces *)
if c.cl_interface then
c.cl_ordered_fields <- List.filter (fun f ->
try
if find_field com c f == f then raise Not_found;
c.cl_fields <- PMap.remove f.cf_name c.cl_fields;
false;
with Not_found ->
true
) c.cl_ordered_fields;
List.iter (fun f ->
match f.cf_expr, f.cf_kind with
| Some { eexpr = TFunction fd }, Method (MethNormal | MethInline) ->
fix_override com c f (Some fd)
| None, Method (MethNormal | MethInline) when c.cl_interface ->
fix_override com c f None
| _ ->
()
) c.cl_ordered_fields
| _ ->
()
(*
PHP does not allow abstract classes extending other abstract classes to override any fields, so these duplicates
must be removed from the child interface
*)
let fix_abstract_inheritance com t =
match t with
| TClassDecl c when c.cl_interface ->
c.cl_ordered_fields <- List.filter (fun f ->
let b = try (find_field com c f) == f
with Not_found -> false in
if not b then c.cl_fields <- PMap.remove f.cf_name c.cl_fields;
b;
) c.cl_ordered_fields
| _ -> ()
(* -------------------------------------------------------------------------- *)
(* MISC FEATURES *)
let rec is_volatile t =
match t with
| TMono r ->
(match !r with
| Some t -> is_volatile t
| _ -> false)
| TLazy f ->
is_volatile (!f())
| TType (t,tl) ->
(match t.t_path with
| _ -> is_volatile (apply_params t.t_params tl t.t_type))
| _ ->
false
let set_default ctx a c p =
let t = a.v_type in
let ve = mk (TLocal a) t p in
let cond = TBinop (OpEq,ve,mk (TConst TNull) t p) in
mk (TIf (mk_parent (mk cond ctx.basic.tbool p), mk (TBinop (OpAssign,ve,mk (TConst c) t p)) t p,None)) ctx.basic.tvoid p
let bytes_serialize data =
let b64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/" in
let tbl = Array.init (String.length b64) (fun i -> String.get b64 i) in
Base64.str_encode ~tbl data
(*
Tells if the constructor might be called without any issue whatever its parameters
*)
let rec constructor_side_effects e =
match e.eexpr with
| TBinop (op,_,_) when op <> OpAssign ->
true
| TField (_,FEnum _) ->
false
| TUnop _ | TArray _ | TField _ | TEnumParameter _ | TCall _ | TNew _ | TFor _ | TWhile _ | TSwitch _ | TReturn _ | TThrow _ ->
true
| TBinop _ | TTry _ | TIf _ | TBlock _ | TVar _
| TFunction _ | TArrayDecl _ | TObjectDecl _
| TParenthesis _ | TTypeExpr _ | TLocal _ | TMeta _
| TConst _ | TContinue | TBreak | TCast _ ->
try
Type.iter (fun e -> if constructor_side_effects e then raise Exit) e;
false;
with Exit ->
true
let make_valid_filename s =
let r = Str.regexp "[^A-Za-z0-9_\\-\\.,]" in
Str.global_substitute r (fun s -> "_") s
(*
Make a dump of the full typed AST of all types
*)
let rec create_dumpfile acc = function
| [] -> assert false
| d :: [] ->
let d = make_valid_filename d in
let ch = open_out (String.concat "/" (List.rev (d :: acc)) ^ ".dump") in
let buf = Buffer.create 0 in
buf, (fun () ->
output_string ch (Buffer.contents buf);
close_out ch)
| d :: l ->
let dir = String.concat "/" (List.rev (d :: acc)) in
if not (Sys.file_exists dir) then Unix.mkdir dir 0o755;
create_dumpfile (d :: acc) l
let dump_types com =
let s_type = s_type (Type.print_context()) in
let params = function [] -> "" | l -> Printf.sprintf "<%s>" (String.concat "," (List.map (fun (n,t) -> n ^ " : " ^ s_type t) l)) in
let s_expr = match Common.defined_value_safe com Define.Dump with
| "pretty" -> Type.s_expr_pretty "\t"
| "legacy" -> Type.s_expr
| _ -> Type.s_expr_ast (not (Common.defined com Define.DumpIgnoreVarIds)) "\t"
in
List.iter (fun mt ->
let path = Type.t_path mt in
let buf,close = create_dumpfile [] ("dump" :: (Common.platform_name com.platform) :: fst path @ [snd path]) in
let print fmt = Printf.kprintf (fun s -> Buffer.add_string buf s) fmt in
(match mt with
| Type.TClassDecl c ->
let rec print_field stat f =
print "\t%s%s%s%s" (if stat then "static " else "") (if f.cf_public then "public " else "") f.cf_name (params f.cf_params);
print "(%s) : %s" (s_kind f.cf_kind) (s_type f.cf_type);
(match f.cf_expr with
| None -> ()
| Some e -> print "\n\n\t = %s" (s_expr s_type e));
print "\n\n";
List.iter (fun f -> print_field stat f) f.cf_overloads
in
print "%s%s%s %s%s" (if c.cl_private then "private " else "") (if c.cl_extern then "extern " else "") (if c.cl_interface then "interface" else "class") (s_type_path path) (params c.cl_params);
(match c.cl_super with None -> () | Some (c,pl) -> print " extends %s" (s_type (TInst (c,pl))));
List.iter (fun (c,pl) -> print " implements %s" (s_type (TInst (c,pl)))) c.cl_implements;
(match c.cl_dynamic with None -> () | Some t -> print " implements Dynamic<%s>" (s_type t));
(match c.cl_array_access with None -> () | Some t -> print " implements ArrayAccess<%s>" (s_type t));
print "{\n";
(match c.cl_constructor with
| None -> ()
| Some f -> print_field false f);
List.iter (print_field false) c.cl_ordered_fields;
List.iter (print_field true) c.cl_ordered_statics;
(match c.cl_init with
| None -> ()
| Some e ->
print "\n\n\t__init__ = ";
print "%s" (s_expr s_type e);
print "}\n");
print "}";
| Type.TEnumDecl e ->
print "%s%senum %s%s {\n" (if e.e_private then "private " else "") (if e.e_extern then "extern " else "") (s_type_path path) (params e.e_params);
List.iter (fun n ->
let f = PMap.find n e.e_constrs in
print "\t%s : %s;\n" f.ef_name (s_type f.ef_type);
) e.e_names;
print "}"
| Type.TTypeDecl t ->
print "%stype %s%s = %s" (if t.t_private then "private " else "") (s_type_path path) (params t.t_params) (s_type t.t_type);
| Type.TAbstractDecl a ->
print "%sabstract %s%s {}" (if a.a_private then "private " else "") (s_type_path path) (params a.a_params);
);
close();
) com.types
let dump_dependencies com =
let buf,close = create_dumpfile [] ["dump";Common.platform_name com.platform;".dependencies"] in
let print fmt = Printf.kprintf (fun s -> Buffer.add_string buf s) fmt in
let dep = Hashtbl.create 0 in
List.iter (fun m ->
print "%s:\n" m.m_extra.m_file;
PMap.iter (fun _ m2 ->
print "\t%s\n" (m2.m_extra.m_file);
let l = try Hashtbl.find dep m2.m_extra.m_file with Not_found -> [] in
Hashtbl.replace dep m2.m_extra.m_file (m :: l)
) m.m_extra.m_deps;
) com.Common.modules;
close();
let buf,close = create_dumpfile [] ["dump";Common.platform_name com.platform;".dependants"] in
let print fmt = Printf.kprintf (fun s -> Buffer.add_string buf s) fmt in
Hashtbl.iter (fun n ml ->
print "%s:\n" n;
List.iter (fun m ->
print "\t%s\n" (m.m_extra.m_file);
) ml;
) dep;
close()
(*
Build a default safe-cast expression :
{ var $t = ; if( Std.is($t,) ) $t else throw "Class cast error"; }
*)
let default_cast ?(vtmp="$t") com e texpr t p =
let api = com.basic in
let mk_texpr = function
| TClassDecl c -> TAnon { a_fields = PMap.empty; a_status = ref (Statics c) }
| TEnumDecl e -> TAnon { a_fields = PMap.empty; a_status = ref (EnumStatics e) }
| TAbstractDecl a -> TAnon { a_fields = PMap.empty; a_status = ref (AbstractStatics a) }
| TTypeDecl _ -> assert false
in
let vtmp = alloc_var vtmp e.etype in
let var = mk (TVar (vtmp,Some e)) api.tvoid p in
let vexpr = mk (TLocal vtmp) e.etype p in
let texpr = mk (TTypeExpr texpr) (mk_texpr texpr) p in
let std = (try List.find (fun t -> t_path t = ([],"Std")) com.types with Not_found -> assert false) in
let fis = (try
let c = (match std with TClassDecl c -> c | _ -> assert false) in
FStatic (c, PMap.find "is" c.cl_statics)
with Not_found ->
assert false
) in
let std = mk (TTypeExpr std) (mk_texpr std) p in
let is = mk (TField (std,fis)) (tfun [t_dynamic;t_dynamic] api.tbool) p in
let is = mk (TCall (is,[vexpr;texpr])) api.tbool p in
let exc = mk (TThrow (mk (TConst (TString "Class cast error")) api.tstring p)) t p in
let check = mk (TIf (mk_parent is,mk (TCast (vexpr,None)) t p,Some exc)) t p in
mk (TBlock [var;check;vexpr]) t p
(** Overload resolution **)
module Overloads =
struct
let rec simplify_t t = match t with
| TAbstract(a,_) when Meta.has Meta.CoreType a.a_meta ->
t
| TInst _ | TEnum _ ->
t
| TAbstract(a,tl) -> simplify_t (Abstract.get_underlying_type a tl)
| TType(({ t_path = [],"Null" } as t), [t2]) -> (match simplify_t t2 with
| (TAbstract(a,_) as t2) when Meta.has Meta.CoreType a.a_meta ->
TType(t, [simplify_t t2])
| (TEnum _ as t2) ->
TType(t, [simplify_t t2])
| t2 -> t2)
| TType(t, tl) ->
simplify_t (apply_params t.t_params tl t.t_type)
| TMono r -> (match !r with
| Some t -> simplify_t t
| None -> t_dynamic)
| TAnon _ -> t_dynamic
| TDynamic _ -> t
| TLazy f -> simplify_t (!f())
| TFun _ -> t
(* rate type parameters *)
let rate_tp tlfun tlarg =
let acc = ref 0 in
List.iter2 (fun f a -> if not (type_iseq f a) then incr acc) tlfun tlarg;
!acc
(**
The rate function returns an ( int * int ) type.
The smaller the int, the best rated the caller argument is in comparison with the callee.
The first int refers to how many "conversions" would be necessary to convert from the callee to the caller type, and
the second refers to the type parameters.
**)
let rec rate_conv cacc tfun targ =
match simplify_t tfun, simplify_t targ with
| TInst({ cl_interface = true } as cf, tlf), TInst(ca, tla) ->
(* breadth-first *)
let stack = ref [0,ca,tla] in
let cur = ref (0, ca,tla) in
let rec loop () =
match !stack with
| [] -> (let acc, ca, tla = !cur in match ca.cl_super with
| None -> raise Not_found
| Some (sup,tls) ->
cur := (acc+1,sup,List.map (apply_params ca.cl_params tla) tls);
stack := [!cur];
loop())
| (acc,ca,tla) :: _ when ca == cf ->
acc,tla
| (acc,ca,tla) :: s ->
stack := s @ List.map (fun (c,tl) -> (acc+1,c,List.map (apply_params ca.cl_params tla) tl)) ca.cl_implements;
loop()
in
let acc, tla = loop() in
(cacc + acc, rate_tp tlf tla)
| TInst(cf,tlf), TInst(ca,tla) ->
let rec loop acc ca tla =
if cf == ca then
acc, tla
else match ca.cl_super with
| None -> raise Not_found
| Some(sup,stl) ->
loop (acc+1) sup (List.map (apply_params ca.cl_params tla) stl)
in
let acc, tla = loop 0 ca tla in
(cacc + acc, rate_tp tlf tla)
| TEnum(ef,tlf), TEnum(ea, tla) ->
if ef != ea then raise Not_found;
(cacc, rate_tp tlf tla)
| TDynamic _, TDynamic _ ->
(cacc, 0)
| TDynamic _, _ ->
(max_int, 0) (* a function with dynamic will always be worst of all *)
| TAbstract(a, _), TDynamic _ when Meta.has Meta.CoreType a.a_meta ->
(cacc + 2, 0) (* a dynamic to a basic type will have an "unboxing" penalty *)
| _, TDynamic _ ->
(cacc + 1, 0)
| TAbstract(af,tlf), TAbstract(aa,tla) ->
(if af == aa then
(cacc, rate_tp tlf tla)
else
let ret = ref None in
if List.exists (fun t -> try
ret := Some (rate_conv (cacc+1) (apply_params af.a_params tlf t) targ);
true
with | Not_found ->
false
) af.a_from then
Option.get !ret
else
if List.exists (fun t -> try
ret := Some (rate_conv (cacc+1) tfun (apply_params aa.a_params tla t));
true
with | Not_found ->
false
) aa.a_to then
Option.get !ret
else
raise Not_found)
| TType({ t_path = [], "Null" }, [tf]), TType({ t_path = [], "Null" }, [ta]) ->
rate_conv (cacc+0) tf ta
| TType({ t_path = [], "Null" }, [tf]), ta ->
rate_conv (cacc+1) tf ta
| tf, TType({ t_path = [], "Null" }, [ta]) ->
rate_conv (cacc+1) tf ta
| TFun _, TFun _ -> (* unify will make sure they are compatible *)
cacc,0
| tfun,targ ->
raise Not_found
let is_best arg1 arg2 =
(List.for_all2 (fun v1 v2 ->
v1 <= v2)
arg1 arg2) && (List.exists2 (fun v1 v2 ->
v1 < v2)
arg1 arg2)
let rec rm_duplicates acc ret = match ret with
| [] -> acc
| ( el, t, _ ) :: ret when List.exists (fun (_,t2,_) -> type_iseq t t2) acc ->
rm_duplicates acc ret
| r :: 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 elist =
List.fold_left (fun acc (_,is_optional) -> if is_optional then acc + 1 else acc) 0 elist
let rec fewer_optionals acc compatible = match acc, compatible with
| _, [] -> acc
| [], c :: comp -> fewer_optionals [c] comp
| (elist_acc, _, _) :: _, ((elist, _, _) as cur) :: comp ->
let acc_opt = count_optionals elist_acc in
let comp_opt = count_optionals elist in
if acc_opt = comp_opt then
fewer_optionals (cur :: acc) comp
else if acc_opt < comp_opt then
fewer_optionals acc comp
else
fewer_optionals [cur] comp
let reduce_compatible compatible = match fewer_optionals [] (rm_duplicates [] compatible) with
| [] -> []
| [v] -> [v]
| compatible ->
(* convert compatible into ( rate * compatible_type ) list *)
let rec mk_rate acc elist args = match elist, args with
| [], [] -> acc
| (_,true) :: elist, _ :: args -> mk_rate acc elist args
| (e,false) :: elist, (n,o,t) :: args ->
(* if the argument is an implicit cast, we need to start with a penalty *)
(* The penalty should be higher than any other implicit cast - other than Dynamic *)
(* since Dynamic has a penalty of max_int, we'll impose max_int - 1 to it *)
(match e.eexpr with
| TMeta( (Meta.ImplicitCast,_,_), _) ->
mk_rate ((max_int - 1, 0) :: acc) elist args
| _ ->
mk_rate (rate_conv 0 t e.etype :: acc) elist args)
| _ -> assert false
in
let rated = ref [] in
List.iter (function
| (elist,TFun(args,ret),d) -> (try
rated := ( (elist,TFun(args,ret),d), mk_rate [] elist args ) :: !rated
with | Not_found -> ())
| _ -> assert false
) compatible;
let rec loop best rem = match best, rem with
| _, [] -> best
| [], r1 :: rem -> loop [r1] rem
| (bover, bargs) :: b1, (rover, rargs) :: rem ->
if is_best bargs rargs then
loop best rem
else if is_best rargs bargs then
loop (loop b1 [rover,rargs]) rem
else (* equally specific *)
loop ( (rover,rargs) :: best ) rem
in
let r = loop [] !rated in
List.map fst r
end;;
module UnificationCallback = struct
let tf_stack = ref []
let check_call_params f el tl =
let rec loop acc el tl = match el,tl with
| e :: el, (n,_,t) :: tl ->
loop ((f e t) :: acc) el tl
| [], [] ->
acc
| [],_ ->
acc
| e :: el, [] ->
loop (e :: acc) el []
in
List.rev (loop [] el tl)
let check_call f el t = match follow t with
| TFun(args,_) ->
check_call_params f el args
| _ ->
List.map (fun e -> f e t_dynamic) el
let rec run f e =
let f e t =
(* TODO: I don't think this should cause errors on Flash target *)
(* if not (type_iseq e.etype t) then f e t else e *)
f e t
in
let check e = match e.eexpr with
| TBinop((OpAssign | OpAssignOp _ as op),e1,e2) ->
let e2 = f e2 e1.etype in
{e with eexpr = TBinop(op,e1,e2)}
| TVar(v,Some ev) ->
let eo = Some (f ev v.v_type) in
{ e with eexpr = TVar(v,eo) }
| TCall(e1,el) ->
let el = check_call f el e1.etype in
{e with eexpr = TCall(e1,el)}
| TNew(c,tl,el) ->
begin try
let tcf,_ = get_constructor (fun cf -> apply_params c.cl_params tl cf.cf_type) c in
let el = check_call f el tcf in
{e with eexpr = TNew(c,tl,el)}
with Not_found ->
e
end
| TArrayDecl el ->
begin match follow e.etype with
| TInst({cl_path=[],"Array"},[t]) -> {e with eexpr = TArrayDecl(List.map (fun e -> f e t) el)}
| _ -> e
end
| TObjectDecl fl ->
begin match follow e.etype with
| TAnon an ->
let fl = List.map (fun (n,e) ->
let e = try
let t = (PMap.find n an.a_fields).cf_type in
f e t
with Not_found ->
e
in
n,e
) fl in
{ e with eexpr = TObjectDecl fl }
| _ -> e
end
| TReturn (Some e1) ->
begin match !tf_stack with
| tf :: _ -> { e with eexpr = TReturn (Some (f e1 tf.tf_type))}
| _ -> e
end
| _ ->
e
in
match e.eexpr with
| TFunction tf ->
tf_stack := tf :: !tf_stack;
let etf = {e with eexpr = TFunction({tf with tf_expr = run f tf.tf_expr})} in
tf_stack := List.tl !tf_stack;
etf
| _ ->
check (Type.map_expr (run f) e)
end;;
module DeprecationCheck = struct
let curclass = ref null_class
let warned_positions = Hashtbl.create 0
let print_deprecation_message com meta s p_usage =
let s = match meta with
| _,[EConst(String s),_],_ -> s
| _ -> Printf.sprintf "Usage of this %s is deprecated" s
in
if not (Hashtbl.mem warned_positions p_usage) then begin
Hashtbl.replace warned_positions p_usage true;
com.warning s p_usage;
end
let check_meta com meta s p_usage =
try
print_deprecation_message com (Meta.get Meta.Deprecated meta) s p_usage;
with Not_found ->
()
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_enum com en p = check_meta com en.e_meta "enum" p
let check_ef com ef p = check_meta com ef.ef_meta "enum field" p
let check_typedef com t p = check_meta com t.t_meta "typedef" p
let check_module_type com mt p = match mt with
| TClassDecl c -> check_class com c p
| TEnumDecl en -> check_enum com en p
| _ -> ()
let run com =
let rec expr e = match e.eexpr with
| TField(e1,fa) ->
expr e1;
begin match fa with
| FStatic(c,cf) | FInstance(c,_,cf) ->
check_class com c e.epos;
check_cf com cf e.epos
| FAnon cf ->
check_cf com cf e.epos
| FClosure(co,cf) ->
(match co with None -> () | Some (c,_) -> check_class com c e.epos);
check_cf com cf e.epos
| FEnum(en,ef) ->
check_enum com en e.epos;
check_ef com ef e.epos;
| _ ->
()
end
| TNew(c,_,el) ->
List.iter expr el;
check_class com c e.epos;
(match c.cl_constructor with None -> () | Some cf -> check_cf com cf e.epos)
| TTypeExpr(mt) | TCast(_,Some mt) ->
check_module_type com mt e.epos
| TMeta((Meta.Deprecated,_,_) as meta,e1) ->
print_deprecation_message com meta "field" e1.epos;
expr e1;
| _ ->
Type.iter expr e
in
List.iter (fun t -> match t with
| TClassDecl c ->
curclass := c;
let field cf = match cf.cf_expr with None -> () | Some e -> expr e in
(match c.cl_constructor with None -> () | Some cf -> field cf);
(match c.cl_init with None -> () | Some e -> expr e);
List.iter field c.cl_ordered_statics;
List.iter field c.cl_ordered_fields;
| _ ->
()
) com.types
end
let interpolate_code com code tl f_string f_expr p =
let exprs = Array.of_list tl in
let i = ref 0 in
let err msg =
let pos = { p with pmin = p.pmin + !i } in
com.error msg pos
in
let regex = Str.regexp "[{}]" in
let rec loop m = match m with
| [] ->
()
| Str.Text txt :: tl ->
i := !i + String.length txt;
f_string txt;
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 ->
(try
let expr = Array.get exprs (int_of_string n) in
f_expr expr;
i := !i + 2 + String.length n;
loop tl
with
| Failure "int_of_string" ->
err ("Index expected. Got " ^ n)
| Invalid_argument _ ->
err ("Out-of-bounds special parameter: " ^ n))
| Str.Delim x :: _ ->
err ("Unexpected " ^ x)
in
loop (Str.full_split regex code)
haxe_3.2.1+dfsg.orig/common.ml 0000664 0001750 0001750 00000131475 12607337712 016161 0 ustar andy andy 0000000 0000000 (*
* Copyright (C)2005-2013 Haxe Foundation
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*)
open Ast
open Type
type package_rule =
| Forbidden
| Directory of string
| Remap of string
type pos = Ast.pos
type basic_types = {
mutable tvoid : t;
mutable tint : t;
mutable tfloat : t;
mutable tbool : t;
mutable tnull : t -> t;
mutable tstring : t;
mutable tarray : t -> t;
}
type stats = {
s_files_parsed : int ref;
s_classes_built : int ref;
s_methods_typed : int ref;
s_macros_called : int ref;
}
type platform =
| Cross
| Js
| Neko
| Flash
| Php
| Cpp
| Cs
| Java
| Python
(**
The capture policy tells which handling we make of captured locals
(the locals which are referenced in local functions)
See details/implementation in Codegen.captured_vars
*)
type capture_policy =
(** do nothing, let the platform handle it *)
| CPNone
(** wrap all captured variables into a single-element array to allow modifications *)
| CPWrapRef
(** similar to wrap ref, but will only apply to the locals that are declared in loops *)
| CPLoopVars
type platform_config = {
(** has a static type system, with not-nullable basic types (Int/Float/Bool) *)
pf_static : bool;
(** has access to the "sys" package *)
pf_sys : bool;
(** local variables are block-scoped *)
pf_locals_scope : bool;
(** captured local variables are scoped *)
pf_captured_scope : bool;
(** generated locals must be absolutely unique wrt the current function *)
pf_unique_locals : bool;
(** captured variables handling (see before) *)
pf_capture_policy : capture_policy;
(** when calling a method with optional args, do we replace the missing args with "null" constants *)
pf_pad_nulls : bool;
(** add a final return to methods not having one already - prevent some compiler warnings *)
pf_add_final_return : bool;
(** does the platform natively support overloaded functions *)
pf_overload : bool;
(** does the platform generator handle pattern matching *)
pf_pattern_matching : bool;
(** can the platform use default values for non-nullable arguments *)
pf_can_skip_non_nullable_argument : bool;
(** type paths that are reserved on the platform *)
pf_reserved_type_paths : path list;
}
type display_mode =
| DMNone
| DMDefault
| DMUsage
| DMPosition
| DMToplevel
| DMResolve of string
| DMType
type context = {
(* config *)
version : int;
args : string list;
mutable sys_args : string list;
mutable display : display_mode;
mutable debug : bool;
mutable verbose : bool;
mutable foptimize : bool;
mutable platform : platform;
mutable config : platform_config;
mutable std_path : string list;
mutable class_path : string list;
mutable main_class : Type.path option;
mutable defines : (string,string) PMap.t;
mutable package_rules : (string,package_rule) PMap.t;
mutable error : string -> pos -> unit;
mutable warning : string -> pos -> unit;
mutable load_extern_type : (path -> pos -> (string * Ast.package) option) list; (* allow finding types which are not in sources *)
mutable filters : (unit -> unit) list;
mutable final_filters : (unit -> unit) list;
mutable defines_signature : string option;
mutable print : string -> unit;
mutable get_macros : unit -> context option;
mutable run_command : string -> int;
file_lookup_cache : (string,string option) Hashtbl.t;
mutable stored_typed_exprs : (int, texpr) PMap.t;
(* output *)
mutable file : string;
mutable flash_version : float;
mutable features : (string,bool) Hashtbl.t;
mutable modules : Type.module_def list;
mutable main : Type.texpr option;
mutable types : Type.module_type list;
mutable resources : (string,string) Hashtbl.t;
mutable neko_libs : string list;
mutable php_front : string option;
mutable php_lib : string option;
mutable php_prefix : string option;
mutable swf_libs : (string * (unit -> Swf.swf) * (unit -> ((string list * string),As3hl.hl_class) Hashtbl.t)) list;
mutable java_libs : (string * bool * (unit -> unit) * (unit -> (path list)) * (path -> ((JData.jclass * string * string) option))) list; (* (path,std,close,all_files,lookup) *)
mutable net_libs : (string * bool * (unit -> path list) * (path -> IlData.ilclass option)) list; (* (path,std,all_files,lookup) *)
mutable net_std : string list;
net_path_map : (path,string list * string list * string) Hashtbl.t;
mutable c_args : string list;
mutable js_gen : (unit -> unit) option;
(* typing *)
mutable basic : basic_types;
memory_marker : float array;
}
exception Abort of string * Ast.pos
let display_default = ref DMNone
module Define = struct
type strict_defined =
| AbsolutePath
| AdvancedTelemetry
| Analyzer
| As3
| CheckXmlProxy
| CoreApi
| CoreApiSerialize
| Cppia
| Dce
| DceDebug
| Debug
| Display
| DllExport
| DllImport
| DocGen
| Dump
| DumpDependencies
| DumpIgnoreVarIds
| EraseGenerics
| Fdb
| FileExtension
| FlashStrict
| FlashUseStage
| ForceLibCheck
| ForceNativeProperty
| FormatWarning
| GencommonDebug
| HaxeBoot
| HaxeVer
| HxcppApiLevel
| IncludePrefix
| Interp
| JavaVer
| JsClassic
| JsEs5
| JsUnflatten
| KeepOldOutput
| LoopUnrollMaxCost
| Macro
| MacroTimes
| NekoSource
| NekoV1
| NetworkSandbox
| NetVer
| NetTarget
| NoCompilation
| NoCOpt
| NoDeprecationWarnings
| NoFlashOverride
| NoDebug
| NoInline
| NoOpt
| NoPatternMatching
| NoRoot
| NoSimplify
| NoSwfCompress
| NoTraces
| PhpPrefix
| RealPosition
| ReplaceFiles
| Scriptable
| ShallowExpose
| SourceMapContent
| Swc
| SwfCompressLevel
| SwfDebugPassword
| SwfDirectBlit
| SwfGpu
| SwfMetadata
| SwfPreloaderFrame
| SwfProtected
| SwfScriptTimeout
| SwfUseDoAbc
| Sys
| Unsafe
| UseNekoc
| UseRttiDoc
| Vcproj
| NoMacroCache
| Last (* must be last *)
let infos = function
| AbsolutePath -> ("absolute_path","Print absolute file path in trace output")
| AdvancedTelemetry -> ("advanced-telemetry","Allow the SWF to be measured with Monocle tool")
| Analyzer -> ("analyzer","Use static analyzer for optimization (experimental)")
| As3 -> ("as3","Defined when outputing flash9 as3 source code")
| CheckXmlProxy -> ("check_xml_proxy","Check the used fields of the xml proxy")
| CoreApi -> ("core_api","Defined in the core api context")
| CoreApiSerialize -> ("core_api_serialize","Sets so some generated core api classes be marked with the Serializable attribute on C#")
| Cppia -> ("cppia", "Generate experimental cpp instruction assembly")
| Dce -> ("dce","The current DCE mode")
| DceDebug -> ("dce_debug","Show DCE log")
| Debug -> ("debug","Activated when compiling with -debug")
| Display -> ("display","Activated during completion")
| DllExport -> ("dll_export", "GenCPP experimental linking")
| DllImport -> ("dll_import", "GenCPP experimental linking")
| DocGen -> ("doc_gen","Do not perform any removal/change in order to correctly generate documentation")
| Dump -> ("dump","Dump the complete typed AST for internal debugging")
| DumpDependencies -> ("dump_dependencies","Dump the classes dependencies")
| DumpIgnoreVarIds -> ("dump_ignore_var_ids","Dump files do not contain variable IDs (helps with diff)")
| EraseGenerics -> ("erase_generics","Erase generic classes on C#")
| Fdb -> ("fdb","Enable full flash debug infos for FDB interactive debugging")
| FileExtension -> ("file_extension","Output filename extension for cpp source code")
| FlashStrict -> ("flash_strict","More strict typing for flash target")
| FlashUseStage -> ("flash_use_stage","Keep the SWF library initial stage")
(* force_lib_check is only here as a debug facility - compiler checking allows errors to be found more easily *)
| ForceLibCheck -> ("force_lib_check","Force the compiler to check -net-lib and -java-lib added classes (internal)")
| ForceNativeProperty -> ("force_native_property","Tag all properties with :nativeProperty metadata for 3.1 compatibility")
| FormatWarning -> ("format_warning","Print a warning for each formated string, for 2.x compatibility")
| GencommonDebug -> ("gencommon_debug","GenCommon internal")
| HaxeBoot -> ("haxe_boot","Given the name 'haxe' to the flash boot class instead of a generated name")
| HaxeVer -> ("haxe_ver","The current Haxe version value")
| HxcppApiLevel -> ("hxcpp_api_level","Provided to allow compatibility between hxcpp versions")
| IncludePrefix -> ("include_prefix","prepend path to generated include files")
| Interp -> ("interp","The code is compiled to be run with --interp")
| JavaVer -> ("java_ver", " Sets the Java version to be targeted")
| JsClassic -> ("js_classic","Don't use a function wrapper and strict mode in JS output")
| JsEs5 -> ("js_es5","Generate JS for ES5-compliant runtimes")
| JsUnflatten -> ("js_unflatten","Generate nested objects for packages and types")
| KeepOldOutput -> ("keep_old_output","Keep old source files in the output directory (for C#/Java)")
| LoopUnrollMaxCost -> ("loop_unroll_max_cost","Maximum cost (number of expressions * iterations) before loop unrolling is canceled (default 250)")
| Macro -> ("macro","Defined when we compile code in the macro context")
| MacroTimes -> ("macro_times","Display per-macro timing when used with --times")
| NetVer -> ("net_ver", " Sets the .NET version to be targeted")
| NetTarget -> ("net_target", " Sets the .NET target. Defaults to \"net\". xbox, micro (Micro Framework), compact (Compact Framework) are some valid values")
| NekoSource -> ("neko_source","Output neko source instead of bytecode")
| NekoV1 -> ("neko_v1","Keep Neko 1.x compatibility")
| NetworkSandbox -> ("network-sandbox","Use local network sandbox instead of local file access one")
| NoCompilation -> ("no-compilation","Disable final compilation for Cs, Cpp and Java")
| NoCOpt -> ("no_copt","Disable completion optimization (for debug purposes)")
| NoDebug -> ("no_debug","Remove all debug macros from cpp output")
| NoDeprecationWarnings -> ("no-deprecation-warnings","Do not warn if fields annotated with @:deprecated are used")
| NoFlashOverride -> ("no-flash-override", "Change overrides on some basic classes into HX suffixed methods, flash only")
| NoOpt -> ("no_opt","Disable optimizations")
| NoPatternMatching -> ("no_pattern_matching","Disable pattern matching")
| NoInline -> ("no_inline","Disable inlining")
| NoRoot -> ("no_root","Generate top-level types into haxe.root namespace")
| NoMacroCache -> ("no_macro_cache","Disable macro context caching")
| NoSimplify -> "no_simplify",("Disable simplification filter")
| NoSwfCompress -> ("no_swf_compress","Disable SWF output compression")
| NoTraces -> ("no_traces","Disable all trace calls")
| PhpPrefix -> ("php_prefix","Compiled with --php-prefix")
| RealPosition -> ("real_position","Disables haxe source mapping when targetting C#")
| ReplaceFiles -> ("replace_files","GenCommon internal")
| Scriptable -> ("scriptable","GenCPP internal")
| ShallowExpose -> ("shallow-expose","Expose types to surrounding scope of Haxe generated closure without writing to window object")
| SourceMapContent -> ("source-map-content","Include the hx sources as part of the JS source map")
| Swc -> ("swc","Output a SWC instead of a SWF")
| SwfCompressLevel -> ("swf_compress_level"," Set the amount of compression for the SWF output")
| SwfDebugPassword -> ("swf_debug_password", "Set a password for debugging")
| SwfDirectBlit -> ("swf_direct_blit", "Use hardware acceleration to blit graphics")
| SwfGpu -> ("swf_gpu", "Use GPU compositing features when drawing graphics")
| SwfMetadata -> ("swf_metadata", "= Include contents of as metadata in the swf")
| SwfPreloaderFrame -> ("swf_preloader_frame", "Insert empty first frame in swf")
| SwfProtected -> ("swf_protected","Compile Haxe private as protected in the SWF instead of public")
| SwfScriptTimeout -> ("swf_script_timeout", "Maximum ActionScript processing time before script stuck dialog box displays (in seconds)")
| SwfUseDoAbc -> ("swf_use_doabc", "Use DoAbc swf-tag instead of DoAbcDefine")
| Sys -> ("sys","Defined for all system platforms")
| Unsafe -> ("unsafe","Allow unsafe code when targeting C#")
| UseNekoc -> ("use_nekoc","Use nekoc compiler instead of internal one")
| UseRttiDoc -> ("use_rtti_doc","Allows access to documentation during compilation")
| Vcproj -> ("vcproj","GenCPP internal")
| Last -> assert false
end
module MetaInfo = struct
open Meta
type meta_usage =
| TClass
| TClassField
| TAbstract
| TAbstractField
| TEnum
| TTypedef
| TAnyField
| TExpr
type meta_parameter =
| HasParam of string
| Platform of platform
| Platforms of platform list
| UsedOn of meta_usage
| UsedOnEither of meta_usage list
| Internal
let to_string = function
| Abi -> ":abi",("Function ABI/calling convention",[Platforms [Cpp]])
| Abstract -> ":abstract",("Sets the underlying class implementation as 'abstract'",[Platforms [Java;Cs]])
| Access -> ":access",("Forces private access to package, type or field",[HasParam "Target path";UsedOnEither [TClass;TClassField]])
| Accessor -> ":accessor",("Used internally by DCE to mark property accessors",[UsedOn TClassField;Internal])
| Allow -> ":allow",("Allows private access from package, type or field",[HasParam "Target path";UsedOnEither [TClass;TClassField]])
| Analyzer -> ":analyzer",("Used to configure the static analyzer",[])
| Annotation -> ":annotation",("Annotation (@interface) definitions on -java-lib imports will be annotated with this metadata. Has no effect on types compiled by Haxe",[Platform Java; UsedOn TClass])
| ArrayAccess -> ":arrayAccess",("Allows [] access on an abstract",[UsedOnEither [TAbstract;TAbstractField]])
| Ast -> ":ast",("Internally used to pass the AST source into the typed AST",[Internal])
| AutoBuild -> ":autoBuild",("Extends @:build metadata to all extending and implementing classes",[HasParam "Build macro call";UsedOn TClass])
| Bind -> ":bind",("Override Swf class declaration",[Platform Flash;UsedOn TClass])
| Bitmap -> ":bitmap",("Embeds given bitmap data into the class (must extend flash.display.BitmapData)",[HasParam "Bitmap file path";UsedOn TClass;Platform Flash])
| BridgeProperties -> ":bridgeProperties",("Creates native property bridges for all Haxe properties in this class",[UsedOn TClass;Platform Cs])
| Build -> ":build",("Builds a class or enum from a macro",[HasParam "Build macro call";UsedOnEither [TClass;TEnum]])
| BuildXml -> ":buildXml",("Specify xml data to be injected into Build.xml",[Platform Cpp])
| Callable -> ":callable",("Abstract forwards call to its underlying type",[UsedOn TAbstract])
| Class -> ":class",("Used internally to annotate an enum that will be generated as a class",[Platforms [Java;Cs]; UsedOn TEnum; Internal])
| ClassCode -> ":classCode",("Used to inject platform-native code into a class",[Platforms [Java;Cs]; UsedOn TClass])
| Commutative -> ":commutative",("Declares an abstract operator as commutative",[UsedOn TAbstractField])
| CompilerGenerated -> ":compilerGenerated",("Marks a field as generated by the compiler. Shouldn't be used by the end user",[Platforms [Java;Cs]])
| CoreApi -> ":coreApi",("Identifies this class as a core api class (forces Api check)",[UsedOnEither [TClass;TEnum;TTypedef;TAbstract]])
| CoreType -> ":coreType",("Identifies an abstract as core type so that it requires no implementation",[UsedOn TAbstract])
| CppFileCode -> ":cppFileCode",("Code to be injected into generated cpp file",[Platform Cpp])
| CppInclude -> ":cppInclude",("File to be included in generated cpp file",[Platform Cpp])
| CppNamespaceCode -> ":cppNamespaceCode",("",[Platform Cpp])
| CsNative -> ":csNative",("Automatically added by -net-lib on classes generated from .NET DLL files",[Platform Cs; UsedOnEither[TClass;TEnum]; Internal])
| Dce -> ":dce",("Forces dead code elimination even when -dce full is not specified",[UsedOnEither [TClass;TEnum]])
| Debug -> ":debug",("Forces debug information to be generated into the Swf even without -debug",[UsedOnEither [TClass;TClassField]; Platform Flash])
| Decl -> ":decl",("",[Platform Cpp])
| DefParam -> ":defParam",("?",[])
| Delegate -> ":delegate",("Automatically added by -net-lib on delegates",[Platform Cs; UsedOn TAbstract])
| Depend -> ":depend",("",[Platform Cpp])
| Deprecated -> ":deprecated",("Automatically added by -java-lib on class fields annotated with @Deprecated annotation. Has no effect on types compiled by Haxe",[Platform Java; UsedOnEither [TClass;TEnum;TClassField]])
| DirectlyUsed -> ":directlyUsed",("Marks types that are directly referenced by non-extern code",[Internal])
| DynamicObject -> ":dynamicObject",("Used internally to identify the Dynamic Object implementation",[Platforms [Java;Cs]; UsedOn TClass; Internal])
| Enum -> ":enum",("Used internally to annotate a class that was generated from an enum",[Platforms [Java;Cs]; UsedOn TClass; Internal])
| EnumConstructorParam -> ":enumConstructorParam",("Used internally to annotate GADT type parameters",[UsedOn TClass; Internal])
| Event -> ":event",("Automatically added by -net-lib on events. Has no effect on types compiled by Haxe",[Platform Cs; UsedOn TClassField])
| Exhaustive -> ":exhaustive",("",[Internal])
| Expose -> ":expose",("Makes the class available on the window object",[HasParam "?Name=Class path";UsedOn TClass;Platform Js])
| Extern -> ":extern",("Marks the field as extern so it is not generated",[UsedOn TClassField])
| FakeEnum -> ":fakeEnum",("Treat enum as collection of values of the specified type",[HasParam "Type name";UsedOn TEnum])
| File -> ":file",("Includes a given binary file into the target Swf and associates it with the class (must extend flash.utils.ByteArray)",[HasParam "File path";UsedOn TClass;Platform Flash])
| Final -> ":final",("Prevents a class from being extended",[UsedOn TClass])
| FlatEnum -> ":flatEnum",("Internally used to mark an enum as being flat, i.e. having no function constructors",[UsedOn TEnum; Internal])
| Font -> ":font",("Embeds the given TrueType font into the class (must extend flash.text.Font)",[HasParam "TTF path";HasParam "Range String";UsedOn TClass])
| Forward -> ":forward",("Forwards field access to underlying type",[HasParam "List of field names";UsedOn TAbstract])
| From -> ":from",("Specifies that the field of the abstract is a cast operation from the type identified in the function",[UsedOn TAbstractField])
| FunctionCode -> ":functionCode",("",[Platform Cpp])
| FunctionTailCode -> ":functionTailCode",("",[Platform Cpp])
| Generic -> ":generic",("Marks a class or class field as generic so each type parameter combination generates its own type/field",[UsedOnEither [TClass;TClassField]])
| GenericBuild -> ":genericBuild",("Builds instances of a type using the specified macro",[UsedOn TClass])
| GenericInstance -> ":genericInstance",("Internally used to mark instances of @:generic methods",[UsedOn TClassField;Internal])
| Getter -> ":getter",("Generates a native getter function on the given field",[HasParam "Class field name";UsedOn TClassField;Platform Flash])
| Hack -> ":hack",("Allows extending classes marked as @:final",[UsedOn TClass])
| HasUntyped -> (":has_untyped",("Used by the typer to mark fields that have untyped expressions",[Internal]))
| HaxeGeneric -> ":haxeGeneric",("Used internally to annotate non-native generic classes",[Platform Cs; UsedOnEither[TClass;TEnum]; Internal])
| HeaderClassCode -> ":headerClassCode",("Code to be injected into the generated class, in the header",[Platform Cpp])
| HeaderCode -> ":headerCode",("Code to be injected into the generated header file",[Platform Cpp])
| HeaderInclude -> ":headerInclude",("File to be included in generated header file",[Platform Cpp])
| HeaderNamespaceCode -> ":headerNamespaceCode",("",[Platform Cpp])
| HxGen -> ":hxGen",("Annotates that an extern class was generated by Haxe",[Platforms [Java;Cs]; UsedOnEither [TClass;TEnum]])
| IfFeature -> ":ifFeature",("Causes a field to be kept by DCE if the given feature is part of the compilation",[HasParam "Feature name";UsedOn TClassField])
| Impl -> ":impl",("Used internally to mark abstract implementation fields",[UsedOn TAbstractField; Internal])
| PythonImport -> ":pythonImport",("Generates python import statement for extern classes",[Platforms [Python]; UsedOn TClass])
| ImplicitCast -> ":implicitCast",("Generated automatically on the AST when an implicit abstract cast happens",[Internal; UsedOn TExpr])
| Include -> ":include",("",[Platform Cpp])
| InitPackage -> ":initPackage",("?",[])
| Meta.Internal -> ":internal",("Generates the annotated field/class with 'internal' access",[Platforms [Java;Cs]; UsedOnEither[TClass;TEnum;TClassField]])
| IsVar -> ":isVar",("Forces a physical field to be generated for properties that otherwise would not require one",[UsedOn TClassField])
| JavaCanonical -> ":javaCanonical",("Used by the Java target to annotate the canonical path of the type",[HasParam "Output type package";HasParam "Output type name";UsedOnEither [TClass;TEnum]; Platform Java])
| JavaNative -> ":javaNative",("Automatically added by -java-lib on classes generated from JAR/class files",[Platform Java; UsedOnEither[TClass;TEnum]; Internal])
| JsRequire -> ":jsRequire",("Generate javascript module require expression for given extern",[Platform Js; UsedOn TClass])
| Keep -> ":keep",("Causes a field or type to be kept by DCE",[])
| KeepInit -> ":keepInit",("Causes a class to be kept by DCE even if all its field are removed",[UsedOn TClass])
| KeepSub -> ":keepSub",("Extends @:keep metadata to all implementing and extending classes",[UsedOn TClass])
| LibType -> ":libType",("Used by -net-lib and -java-lib to mark a class that shouldn't be checked (overrides, interfaces, etc) by the type loader",[Internal; UsedOn TClass; Platforms [Java;Cs]])
| Meta -> ":meta",("Internally used to mark a class field as being the metadata field",[])
| Macro -> ":macro",("(deprecated)",[])
| MaybeUsed -> ":maybeUsed",("Internally used by DCE to mark fields that might be kept",[Internal])
| MergeBlock -> ":mergeBlock",("Merge the annotated block into the current scope",[UsedOn TExpr])
| MultiType -> ":multiType",("Specifies that an abstract chooses its this-type from its @:to functions",[UsedOn TAbstract; HasParam "Relevant type parameters"])
| Native -> ":native",("Rewrites the path of a class or enum during generation",[HasParam "Output type path";UsedOnEither [TClass;TEnum]])
| NativeChildren -> ":nativeChildren",("Annotates that all children from a type should be treated as if it were an extern definition - platform native",[Platforms [Java;Cs]; UsedOn TClass])
| NativeGen -> ":nativeGen",("Annotates that a type should be treated as if it were an extern definition - platform native",[Platforms [Java;Cs;Python]; UsedOnEither[TClass;TEnum]])
| NativeGeneric -> ":nativeGeneric",("Used internally to annotate native generic classes",[Platform Cs; UsedOnEither[TClass;TEnum]; Internal])
| NativeProperty -> ":nativeProperty",("Use native properties which will execute even with dynamic usage",[Platform Cpp])
| NoCompletion -> ":noCompletion",("Prevents the compiler from suggesting completion on this field",[UsedOn TClassField])
| NoDebug -> ":noDebug",("Does not generate debug information into the Swf even if -debug is set",[UsedOnEither [TClass;TClassField];Platform Flash])
| NoDoc -> ":noDoc",("Prevents a type from being included in documentation generation",[])
| NoExpr -> ":noExpr",("Internally used to mark abstract fields which have no expression by design",[Internal])
| NoImportGlobal -> ":noImportGlobal",("Prevents a static field from being imported with import Class.*",[UsedOn TAnyField])
| NonVirtual -> ":nonVirtual",("Declares function to be non-virtual in cpp",[Platform Cpp])
| NoPackageRestrict -> ":noPackageRestrict",("Allows a module to be accessed across all targets if found on its first type",[Internal])
| NoPrivateAccess -> ":noPrivateAccess",("Disallow private access to anything for the annotated expression",[UsedOn TExpr])
| NoStack -> ":noStack",("",[Platform Cpp])
| NotNull -> ":notNull",("Declares an abstract type as not accepting null values",[UsedOn TAbstract])
| NoUsing -> ":noUsing",("Prevents a field from being used with 'using'",[UsedOn TClassField])
| Ns -> ":ns",("Internally used by the Swf generator to handle namespaces",[Platform Flash])
| Op -> ":op",("Declares an abstract field as being an operator overload",[HasParam "The operation";UsedOn TAbstractField])
| Optional -> ":optional",("Marks the field of a structure as optional",[UsedOn TClassField])
| Overload -> ":overload",("Allows the field to be called with different argument types",[HasParam "Function specification (no expression)";UsedOn TClassField])
| Public -> ":public",("Marks a class field as being public",[UsedOn TClassField])
| PublicFields -> ":publicFields",("Forces all class fields of inheriting classes to be public",[UsedOn TClass])
| QuotedField -> ":quotedField",("Used internally to mark structure fields which are quoted in syntax",[Internal])
| PrivateAccess -> ":privateAccess",("Allow private access to anything for the annotated expression",[UsedOn TExpr])
| Protected -> ":protected",("Marks a class field as being protected",[UsedOn TClassField])
| Property -> ":property",("Marks a property field to be compiled as a native C# property",[UsedOn TClassField;Platform Cs])
| ReadOnly -> ":readOnly",("Generates a field with the 'readonly' native keyword",[Platform Cs; UsedOn TClassField])
| RealPath -> ":realPath",("Internally used on @:native types to retain original path information",[Internal])
| Remove -> ":remove",("Causes an interface to be removed from all implementing classes before generation",[UsedOn TClass])
| Require -> ":require",("Allows access to a field only if the specified compiler flag is set",[HasParam "Compiler flag to check";UsedOn TClassField])
| RequiresAssign -> ":requiresAssign",("Used internally to mark certain abstract operator overloads",[Internal])
(* | Resolve -> ":resolve",("Abstract fields marked with this metadata can be used to resolve unknown fields",[UsedOn TClassField]) *)
| ReplaceReflection -> ":replaceReflection",("Used internally to specify a function that should replace its internal __hx_functionName counterpart",[Platforms [Java;Cs]; UsedOnEither[TClass;TEnum]; Internal])
| Rtti -> ":rtti",("Adds runtime type informations",[UsedOn TClass])
| Runtime -> ":runtime",("?",[])
| RuntimeValue -> ":runtimeValue",("Marks an abstract as being a runtime value",[UsedOn TAbstract])
| SelfCall -> ":selfCall",("Translates method calls into calling object directly",[UsedOn TClassField; Platform Js])
| Setter -> ":setter",("Generates a native setter function on the given field",[HasParam "Class field name";UsedOn TClassField;Platform Flash])
| StoredTypedExpr -> ":storedTypedExpr",("Used internally to reference a typed expression returned from a macro",[Internal])
| SkipCtor -> ":skipCtor",("Used internally to generate a constructor as if it were a native type (no __hx_ctor)",[Platforms [Java;Cs]; Internal])
| SkipReflection -> ":skipReflection",("Used internally to annotate a field that shouldn't have its reflection data generated",[Platforms [Java;Cs]; UsedOn TClassField; Internal])
| Sound -> ":sound",( "Includes a given .wav or .mp3 file into the target Swf and associates it with the class (must extend flash.media.Sound)",[HasParam "File path";UsedOn TClass;Platform Flash])
| SourceFile -> ":sourceFile",("Source code filename for external class",[Platform Cpp])
| Strict -> ":strict",("Used to declare a native C# attribute or a native Java metadata. Is type checked",[Platforms [Java;Cs]])
| Struct -> ":struct",("Marks a class definition as a struct",[Platform Cs; UsedOn TClass])
| StructAccess -> ":structAccess",("Marks an extern class as using struct access('.') not pointer('->')",[Platform Cpp; UsedOn TClass])
| SuppressWarnings -> ":suppressWarnings",("Adds a SuppressWarnings annotation for the generated Java class",[Platform Java; UsedOn TClass])
| Throws -> ":throws",("Adds a 'throws' declaration to the generated function",[HasParam "Type as String"; Platform Java; UsedOn TClassField])
| This -> ":this",("Internally used to pass a 'this' expression to macros",[Internal; UsedOn TExpr])
| To -> ":to",("Specifies that the field of the abstract is a cast operation to the type identified in the function",[UsedOn TAbstractField])
| ToString -> ":toString",("Internally used",[Internal])
| Transient -> ":transient",("Adds the 'transient' flag to the class field",[Platform Java; UsedOn TClassField])
| ValueUsed -> ":valueUsed",("Internally used by DCE to mark an abstract value as used",[Internal])
| Volatile -> ":volatile",("",[Platforms [Java;Cs]])
| Unbound -> ":unbound", ("Compiler internal to denote unbounded global variable",[])
| UnifyMinDynamic -> ":unifyMinDynamic",("Allows a collection of types to unify to Dynamic",[UsedOn TClassField])
| Unreflective -> ":unreflective",("",[Platform Cpp])
| Unsafe -> ":unsafe",("Declares a class, or a method with the C#'s 'unsafe' flag",[Platform Cs; UsedOnEither [TClass;TClassField]])
| Usage -> ":usage",("?",[])
| Used -> ":used",("Internally used by DCE to mark a class or field as used",[Internal])
| Value -> ":value",("Used to store default values for fields and function arguments",[UsedOn TClassField])
| Void -> ":void",("Use Cpp native 'void' return type",[Platform Cpp])
| Last -> assert false
(* do not put any custom metadata after Last *)
| Dollar s -> "$" ^ s,("",[])
| Custom s -> s,("",[])
let hmeta =
let h = Hashtbl.create 0 in
let rec loop i =
let m = Obj.magic i in
if m <> Last then begin
Hashtbl.add h (fst (to_string m)) m;
loop (i + 1);
end;
in
loop 0;
h
let parse s = try Hashtbl.find hmeta (":" ^ s) with Not_found -> Custom (":" ^ s)
let from_string s =
if s = "" then Custom "" else match s.[0] with
| ':' -> (try Hashtbl.find hmeta s with Not_found -> Custom s)
| '$' -> Dollar (String.sub s 1 (String.length s - 1))
| _ -> Custom s
end
let stats =
{
s_files_parsed = ref 0;
s_classes_built = ref 0;
s_methods_typed = ref 0;
s_macros_called = ref 0;
}
let default_config =
{
pf_static = true;
pf_sys = true;
pf_locals_scope = true;
pf_captured_scope = true;
pf_unique_locals = false;
pf_capture_policy = CPNone;
pf_pad_nulls = false;
pf_add_final_return = false;
pf_overload = false;
pf_pattern_matching = false;
pf_can_skip_non_nullable_argument = true;
pf_reserved_type_paths = [];
}
let get_config com =
let defined f = PMap.mem (fst (Define.infos f)) com.defines in
match com.platform with
| Cross ->
default_config
| Js ->
{
pf_static = false;
pf_sys = false;
pf_locals_scope = false;
pf_captured_scope = false;
pf_unique_locals = false;
pf_capture_policy = CPLoopVars;
pf_pad_nulls = false;
pf_add_final_return = false;
pf_overload = false;
pf_pattern_matching = false;
pf_can_skip_non_nullable_argument = true;
pf_reserved_type_paths = [([],"Object");([],"Error")];
}
| Neko ->
{
pf_static = false;
pf_sys = true;
pf_locals_scope = true;
pf_captured_scope = true;
pf_unique_locals = false;
pf_capture_policy = CPNone;
pf_pad_nulls = true;
pf_add_final_return = false;
pf_overload = false;
pf_pattern_matching = false;
pf_can_skip_non_nullable_argument = true;
pf_reserved_type_paths = [];
}
| Flash when defined Define.As3 ->
{
pf_static = true;
pf_sys = false;
pf_locals_scope = false;
pf_captured_scope = true;
pf_unique_locals = true;
pf_capture_policy = CPLoopVars;
pf_pad_nulls = false;
pf_add_final_return = true;
pf_overload = false;
pf_pattern_matching = false;
pf_can_skip_non_nullable_argument = false;
pf_reserved_type_paths = [];
}
| Flash ->
{
pf_static = true;
pf_sys = false;
pf_locals_scope = true;
pf_captured_scope = true; (* handled by genSwf9 *)
pf_unique_locals = false;
pf_capture_policy = CPLoopVars;
pf_pad_nulls = false;
pf_add_final_return = false;
pf_overload = false;
pf_pattern_matching = false;
pf_can_skip_non_nullable_argument = false;
pf_reserved_type_paths = [([],"Object");([],"Error")];
}
| Php ->
{
pf_static = false;
pf_sys = true;
pf_locals_scope = false; (* some duplicate work is done in genPhp *)
pf_captured_scope = false;
pf_unique_locals = false;
pf_capture_policy = CPNone;
pf_pad_nulls = true;
pf_add_final_return = false;
pf_overload = false;
pf_pattern_matching = false;
pf_can_skip_non_nullable_argument = true;
pf_reserved_type_paths = [];
}
| Cpp ->
{
pf_static = true;
pf_sys = true;
pf_locals_scope = true;
pf_captured_scope = true;
pf_unique_locals = false;
pf_capture_policy = CPWrapRef;
pf_pad_nulls = true;
pf_add_final_return = true;
pf_overload = false;
pf_pattern_matching = false;
pf_can_skip_non_nullable_argument = true;
pf_reserved_type_paths = [];
}
| Cs ->
{
pf_static = true;
pf_sys = true;
pf_locals_scope = false;
pf_captured_scope = true;
pf_unique_locals = true;
pf_capture_policy = CPWrapRef;
pf_pad_nulls = true;
pf_add_final_return = false;
pf_overload = true;
pf_pattern_matching = false;
pf_can_skip_non_nullable_argument = true;
pf_reserved_type_paths = [];
}
| Java ->
{
pf_static = true;
pf_sys = true;
pf_locals_scope = false;
pf_captured_scope = true;
pf_unique_locals = false;
pf_capture_policy = CPWrapRef;
pf_pad_nulls = true;
pf_add_final_return = false;
pf_overload = true;
pf_pattern_matching = false;
pf_can_skip_non_nullable_argument = true;
pf_reserved_type_paths = [];
}
| Python ->
{
pf_static = false;
pf_sys = true;
pf_locals_scope = false;
pf_captured_scope = false;
pf_unique_locals = false;
pf_capture_policy = CPLoopVars;
pf_pad_nulls = false;
pf_add_final_return = false;
pf_overload = false;
pf_pattern_matching = false;
pf_can_skip_non_nullable_argument = true;
pf_reserved_type_paths = [];
}
let memory_marker = [|Unix.time()|]
let create v args =
let m = Type.mk_mono() in
{
version = v;
args = args;
sys_args = args;
debug = false;
display = !display_default;
verbose = false;
foptimize = true;
features = Hashtbl.create 0;
platform = Cross;
config = default_config;
print = (fun s -> print_string s; flush stdout);
run_command = Sys.command;
std_path = [];
class_path = [];
main_class = None;
defines = PMap.add "true" "1" (if !display_default <> DMNone then PMap.add "display" "1" PMap.empty else PMap.empty);
package_rules = PMap.empty;
file = "";
types = [];
filters = [];
final_filters = [];
modules = [];
main = None;
flash_version = 10.;
resources = Hashtbl.create 0;
php_front = None;
php_lib = None;
swf_libs = [];
java_libs = [];
net_libs = [];
net_std = [];
net_path_map = Hashtbl.create 0;
c_args = [];
neko_libs = [];
php_prefix = None;
js_gen = None;
load_extern_type = [];
defines_signature = None;
get_macros = (fun() -> None);
warning = (fun _ _ -> assert false);
error = (fun _ _ -> assert false);
basic = {
tvoid = m;
tint = m;
tfloat = m;
tbool = m;
tnull = (fun _ -> assert false);
tstring = m;
tarray = (fun _ -> assert false);
};
file_lookup_cache = Hashtbl.create 0;
stored_typed_exprs = PMap.empty;
memory_marker = memory_marker;
}
let log com str =
if com.verbose then com.print (str ^ "\n")
let clone com =
let t = com.basic in
{ com with
basic = { t with tvoid = t.tvoid };
main_class = None;
features = Hashtbl.create 0;
file_lookup_cache = Hashtbl.create 0;
}
let file_time file =
try (Unix.stat file).Unix.st_mtime with _ -> 0.
let get_signature com =
match com.defines_signature with
| Some s -> s
| None ->
let str = String.concat "@" (PMap.foldi (fun k v acc ->
(* don't make much difference between these special compilation flags *)
match k with
| "display" | "use_rtti_doc" | "macrotimes" -> acc
| _ -> k :: v :: acc
) com.defines []) in
let s = Digest.string str in
com.defines_signature <- Some s;
s
let file_extension file =
match List.rev (ExtString.String.nsplit file ".") with
| e :: _ -> String.lowercase e
| [] -> ""
let platforms = [
Js;
Neko;
Flash;
Php;
Cpp;
Cs;
Java;
Python;
]
let platform_name = function
| Cross -> "cross"
| Js -> "js"
| Neko -> "neko"
| Flash -> "flash"
| Php -> "php"
| Cpp -> "cpp"
| Cs -> "cs"
| Java -> "java"
| Python -> "python"
let flash_versions = List.map (fun v ->
let maj = int_of_float v in
let min = int_of_float (mod_float (v *. 10.) 10.) in
v, string_of_int maj ^ (if min = 0 then "" else "_" ^ string_of_int min)
) [9.;10.;10.1;10.2;10.3;11.;11.1;11.2;11.3;11.4;11.5;11.6;11.7;11.8;11.9;12.0;13.0;14.0;15.0;16.0;17.0]
let flash_version_tag = function
| 6. -> 6
| 7. -> 7
| 8. -> 8
| 9. -> 9
| 10. | 10.1 -> 10
| 10.2 -> 11
| 10.3 -> 12
| 11. -> 13
| 11.1 -> 14
| 11.2 -> 15
| 11.3 -> 16
| 11.4 -> 17
| 11.5 -> 18
| 11.6 -> 19
| 11.7 -> 20
| 11.8 -> 21
| 11.9 -> 22
| 12.0 -> 23
| 13.0 -> 24
| 14.0 -> 25
| 15.0 -> 26
| 16.0 -> 27
| 17.0 -> 28
| v -> failwith ("Invalid SWF version " ^ string_of_float v)
let raw_defined ctx v =
PMap.mem v ctx.defines
let defined ctx v =
raw_defined ctx (fst (Define.infos v))
let raw_defined_value ctx k =
PMap.find k ctx.defines
let defined_value ctx v =
raw_defined_value ctx (fst (Define.infos v))
let defined_value_safe ctx v =
try defined_value ctx v
with Not_found -> ""
let raw_define ctx v =
let k,v = try ExtString.String.split v "=" with _ -> v,"1" in
ctx.defines <- PMap.add k v ctx.defines;
let k = String.concat "_" (ExtString.String.nsplit k "-") in
ctx.defines <- PMap.add k v ctx.defines;
ctx.defines_signature <- None
let define_value ctx k v =
raw_define ctx (fst (Define.infos k) ^ "=" ^ v)
let define ctx v =
raw_define ctx (fst (Define.infos v))
let init_platform com pf =
com.platform <- pf;
let name = platform_name pf 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 (List.map platform_name platforms);
com.config <- get_config com;
(* if com.config.pf_static then define com "static"; *)
if com.config.pf_sys then define com Define.Sys else com.package_rules <- PMap.add "sys" Forbidden com.package_rules;
raw_define com name
let add_feature com f =
Hashtbl.replace com.features f true
let has_dce com =
(try defined_value com Define.Dce <> "no" with Not_found -> false)
(*
TODO: The has_dce check is there because we mark types with @:directlyUsed in the DCE filter,
which is not run in dce=no and thus we can't know if a type is used directly or not,
so we just assume that they are.
If we had dce filter always running (even with dce=no), we would have types marked with @:directlyUsed
and we wouldn't need to generate unnecessary imports in dce=no, but that's good enough for now.
*)
let is_directly_used com meta =
not (has_dce com) || Ast.Meta.has Ast.Meta.DirectlyUsed meta
let rec has_feature com f =
try
Hashtbl.find com.features f
with Not_found ->
if com.types = [] then not (has_dce com) else
match List.rev (ExtString.String.nsplit f ".") with
| [] -> assert false
| [cl] -> has_feature com (cl ^ ".*")
| meth :: cl :: pack ->
let r = (try
let path = List.rev pack, cl in
(match List.find (fun t -> t_path t = path && not (Ast.Meta.has Ast.Meta.RealPath (t_infos t).mt_meta)) com.types with
| t when meth = "*" -> (match t with TAbstractDecl a -> Ast.Meta.has Ast.Meta.ValueUsed a.a_meta | _ ->
Ast.Meta.has Ast.Meta.Used (t_infos t).mt_meta)
| TClassDecl ({cl_extern = true} as c) when com.platform <> Js || cl <> "Array" && cl <> "Math" ->
Meta.has Meta.Used (try PMap.find meth c.cl_statics with Not_found -> PMap.find meth c.cl_fields).cf_meta
| TClassDecl c ->
PMap.exists meth c.cl_statics || PMap.exists meth c.cl_fields
| _ ->
false)
with Not_found ->
false
) in
let r = r || not (has_dce com) in
Hashtbl.add com.features f r;
r
let allow_package ctx s =
try
if (PMap.find s ctx.package_rules) = Forbidden then ctx.package_rules <- PMap.remove s ctx.package_rules
with Not_found ->
()
let error msg p = raise (Abort (msg,p))
let platform ctx p = ctx.platform = p
let add_filter ctx f =
ctx.filters <- f :: ctx.filters
let add_final_filter ctx f =
ctx.final_filters <- f :: ctx.final_filters
let find_file ctx f =
try
(match Hashtbl.find ctx.file_lookup_cache f with
| None -> raise Exit
| Some f -> f)
with Exit ->
raise Not_found
| Not_found ->
let rec loop had_empty = function
| [] when had_empty -> raise Not_found
| [] -> loop true [""]
| p :: l ->
let file = p ^ f in
if Sys.file_exists file then
file
else
loop (had_empty || p = "") l
in
let r = (try Some (loop false ctx.class_path) with Not_found -> None) in
Hashtbl.add ctx.file_lookup_cache f r;
(match r with
| None -> raise Not_found
| Some f -> f)
let get_full_path f = try Extc.get_full_path f with _ -> f
let unique_full_path = if Sys.os_type = "Win32" || Sys.os_type = "Cygwin" then (fun f -> String.lowercase (get_full_path f)) else get_full_path
let normalize_path p =
let l = String.length p in
if l = 0 then
"./"
else match p.[l-1] with
| '\\' | '/' -> p
| _ -> p ^ "/"
let rec mkdir_recursive base dir_list =
match dir_list with
| [] -> ()
| dir :: remaining ->
let path = match base with
| "" -> dir
| "/" -> "/" ^ dir
| _ -> base ^ "/" ^ dir
in
if not ( (path = "") || ( ((String.length path) = 2) && ((String.sub path 1 1) = ":") ) ) then
if not (Sys.file_exists path) then
Unix.mkdir path 0o755;
mkdir_recursive (if (path = "") then "/" else path) remaining
let mkdir_from_path path =
let parts = Str.split_delim (Str.regexp "[\\/]+") path in
match parts with
| [] -> (* path was "" *) ()
| _ ->
let dir_list = List.rev (List.tl (List.rev parts)) in
mkdir_recursive "" dir_list
let mem_size v =
Objsize.size_with_headers (Objsize.objsize v [] [])
(* ------------------------- TIMERS ----------------------------- *)
type timer_infos = {
name : string;
mutable start : float list;
mutable total : float;
}
let get_time = Extc.time
let htimers = Hashtbl.create 0
let new_timer name =
try
let t = Hashtbl.find htimers name in
t.start <- get_time() :: t.start;
t
with Not_found ->
let t = { name = name; start = [get_time()]; total = 0.; } in
Hashtbl.add htimers name t;
t
let curtime = ref []
let close t =
let start = (match t.start with
| [] -> assert false
| s :: l -> t.start <- l; s
) in
let now = get_time() in
let dt = now -. start in
t.total <- t.total +. dt;
let rec loop() =
match !curtime with
| [] -> failwith ("Timer " ^ t.name ^ " closed while not active")
| tt :: l -> curtime := l; if t != tt then loop()
in
loop();
(* because of rounding errors while adding small times, we need to make sure that we don't have start > now *)
List.iter (fun ct -> ct.start <- List.map (fun t -> let s = t +. dt in if s > now then now else s) ct.start) !curtime
let timer name =
let t = new_timer name in
curtime := t :: !curtime;
(function() -> close t)
let rec close_times() =
match !curtime with
| [] -> ()
| t :: _ -> close t; close_times()
;;
Ast.Meta.to_string_ref := fun m -> fst (MetaInfo.to_string m)
(* Taken from OCaml source typing/oprint.ml
This is a better version of string_of_float which prints without loss of precision
so that float_of_string (float_repres x) = x for all floats x
*)
let valid_float_lexeme s =
let l = String.length s in
let rec loop i =
if i >= l then s ^ "." else
match s.[i] with
| '0' .. '9' | '-' -> loop (i+1)
| _ -> s
in loop 0
let float_repres f =
match classify_float f with
| FP_nan -> "nan"
| FP_infinite ->
if f < 0.0 then "neg_infinity" else "infinity"
| _ ->
let float_val =
let s1 = Printf.sprintf "%.12g" f in
if f = float_of_string s1 then s1 else
let s2 = Printf.sprintf "%.15g" f in
if f = float_of_string s2 then s2 else
Printf.sprintf "%.18g" f
in valid_float_lexeme float_val
haxe_3.2.1+dfsg.orig/dce.ml 0000664 0001750 0001750 00000060103 12607337712 015411 0 ustar andy andy 0000000 0000000 (*
* Copyright (C)2005-2013 Haxe Foundation
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*)
open Ast
open Common
open Type
type dce = {
com : context;
full : bool;
std_dirs : string list;
debug : bool;
follow_expr : dce -> texpr -> unit;
mutable curclass : tclass;
mutable added_fields : (tclass * tclass_field * bool) list;
mutable marked_fields : tclass_field list;
mutable marked_maybe_fields : tclass_field list;
mutable t_stack : t list;
mutable ts_stack : t list;
mutable features : (string,(tclass * tclass_field * bool) list) Hashtbl.t;
}
(* checking *)
(* check for @:keepSub metadata, which forces @:keep on child classes *)
let rec super_forces_keep c =
Meta.has Meta.KeepSub c.cl_meta || match c.cl_super with
| Some (csup,_) -> super_forces_keep csup
| _ -> false
let is_std_file dce file =
List.exists (ExtString.String.starts_with file) dce.std_dirs
(* check if a class is kept entirely *)
let keep_whole_class dce c =
Meta.has Meta.Keep c.cl_meta
|| not (dce.full || is_std_file dce c.cl_module.m_extra.m_file || has_meta Meta.Dce c.cl_meta)
|| super_forces_keep c
|| (match c with
| { cl_path = ([],("Math"|"Array"))} when dce.com.platform = Js -> false
| { cl_extern = true }
| { cl_path = ["flash";"_Boot"],"RealBoot" } -> true
| { cl_path = [],"String" }
| { cl_path = [],"Array" } -> not (dce.com.platform = Js)
| _ -> false)
let keep_whole_enum dce en =
Meta.has Meta.Keep en.e_meta
|| not (dce.full || is_std_file dce en.e_module.m_extra.m_file || has_meta Meta.Dce en.e_meta)
(* check if a field is kept *)
let keep_field dce cf =
Meta.has Meta.Keep cf.cf_meta
|| Meta.has Meta.Used cf.cf_meta
|| cf.cf_name = "__init__"
|| is_extern_field cf
(* marking *)
let rec check_feature dce s =
try
let l = Hashtbl.find dce.features s in
List.iter (fun (c,cf,stat) ->
mark_field dce c cf stat
) l;
Hashtbl.remove dce.features s;
with Not_found ->
()
and check_and_add_feature dce s =
check_feature dce s;
Common.add_feature dce.com s;
(* mark a field as kept *)
and mark_field dce c cf stat =
let add cf =
if not (Meta.has Meta.Used cf.cf_meta) then begin
cf.cf_meta <- (Meta.Used,[],cf.cf_pos) :: cf.cf_meta;
dce.added_fields <- (c,cf,stat) :: dce.added_fields;
dce.marked_fields <- cf :: dce.marked_fields;
check_feature dce (Printf.sprintf "%s.%s" (s_type_path c.cl_path) cf.cf_name);
end
in
if cf.cf_name = "new" then begin
let rec loop c = match c.cl_super with
| None -> ()
| Some (csup,_) ->
begin match csup.cl_constructor with
| None -> ()
| Some cf -> add cf
end;
loop csup
in
loop c
end;
if not (PMap.mem cf.cf_name (if stat then c.cl_statics else c.cl_fields)) then begin
match c.cl_super with
| None -> add cf
| Some (c,_) -> mark_field dce c cf stat
end else
add cf
let rec update_marked_class_fields dce c =
(* mark all :?used fields as surely :used now *)
List.iter (fun cf ->
if Meta.has Meta.MaybeUsed cf.cf_meta then mark_field dce c cf true
) c.cl_ordered_statics;
List.iter (fun cf ->
if Meta.has Meta.MaybeUsed cf.cf_meta then mark_field dce c cf false
) c.cl_ordered_fields;
(* we always have to keep super classes and implemented interfaces *)
(match c.cl_init with None -> () | Some init -> dce.follow_expr dce init);
List.iter (fun (c,_) -> mark_class dce c) c.cl_implements;
(match c.cl_super with None -> () | Some (csup,pl) -> mark_class dce csup)
(* mark a class as kept. If the class has fields marked as @:?keep, make sure to keep them *)
and mark_class dce c = if not (Meta.has Meta.Used c.cl_meta) then begin
c.cl_meta <- (Meta.Used,[],c.cl_pos) :: c.cl_meta;
check_feature dce (Printf.sprintf "%s.*" (s_type_path c.cl_path));
update_marked_class_fields dce c;
end
let rec mark_enum dce e = if not (Meta.has Meta.Used e.e_meta) then begin
e.e_meta <- (Meta.Used,[],e.e_pos) :: e.e_meta;
check_and_add_feature dce "has_enum";
check_feature dce (Printf.sprintf "%s.*" (s_type_path e.e_path));
PMap.iter (fun _ ef -> mark_t dce ef.ef_pos ef.ef_type) e.e_constrs;
end
and mark_abstract dce a = if not (Meta.has Meta.Used a.a_meta) then begin
check_feature dce (Printf.sprintf "%s.*" (s_type_path a.a_path));
a.a_meta <- (Meta.Used,[],a.a_pos) :: a.a_meta
end
(* mark a type as kept *)
and mark_t dce p t =
if not (List.exists (fun t2 -> Type.fast_eq t t2) dce.t_stack) then begin
dce.t_stack <- t :: dce.t_stack;
begin match follow t with
| TInst({cl_kind = KTypeParameter tl} as c,pl) ->
if not (Meta.has Meta.Used c.cl_meta) then begin
c.cl_meta <- (Meta.Used,[],c.cl_pos) :: c.cl_meta;
List.iter (mark_t dce p) tl;
end;
List.iter (mark_t dce p) pl
| TInst(c,pl) ->
mark_class dce c;
List.iter (mark_t dce p) pl
| TFun(args,ret) ->
List.iter (fun (_,_,t) -> mark_t dce p t) args;
mark_t dce p ret
| TEnum(e,pl) ->
mark_enum dce e;
List.iter (mark_t dce p) pl
| TAbstract(a,pl) when Meta.has Meta.MultiType a.a_meta ->
begin try
mark_t dce p (snd (Codegen.AbstractCast.find_multitype_specialization dce.com a pl p))
with Typecore.Error _ ->
()
end
| TAbstract(a,pl) ->
mark_abstract dce a;
List.iter (mark_t dce p) pl;
if not (Meta.has Meta.CoreType a.a_meta) then
mark_t dce p (Abstract.get_underlying_type a pl)
| TLazy _ | TDynamic _ | TType _ | TAnon _ | TMono _ -> ()
end;
dce.t_stack <- List.tl dce.t_stack
end
let mark_mt dce mt = match mt with
| TClassDecl c ->
mark_class dce c;
| TEnumDecl e ->
mark_enum dce e
| TAbstractDecl a ->
(* abstract 'feature' is defined as the abstract type beeing used as a value, not as a type *)
if not (Meta.has Meta.ValueUsed a.a_meta) then a.a_meta <- (Meta.ValueUsed,[],a.a_pos) :: a.a_meta;
mark_abstract dce a
| TTypeDecl _ ->
()
(* find all dependent fields by checking implementing/subclassing types *)
let rec mark_dependent_fields dce csup n stat =
List.iter (fun mt -> match mt with
| TClassDecl c when is_parent csup c ->
let rec loop c =
(try
let cf = PMap.find n (if stat then c.cl_statics else c.cl_fields) in
(* if it's clear that the class is kept, the field has to be kept as well. This is also true for
extern interfaces because we cannot remove fields from them *)
if Meta.has Meta.Used c.cl_meta || (csup.cl_interface && csup.cl_extern) then mark_field dce c cf stat
(* otherwise it might be kept if the class is kept later, so mark it as :?used *)
else if not (Meta.has Meta.MaybeUsed cf.cf_meta) then begin
cf.cf_meta <- (Meta.MaybeUsed,[],cf.cf_pos) :: cf.cf_meta;
dce.marked_maybe_fields <- cf :: dce.marked_maybe_fields;
end
with Not_found ->
(* if the field is not present on current class, it might come from a base class *)
(match c.cl_super with None -> () | Some (csup,_) -> loop csup))
in
loop c
| _ -> ()
) dce.com.types
(* expr and field evaluation *)
let opt f e = match e with None -> () | Some e -> f e
let rec to_string dce t = match t with
| TInst(c,tl) ->
field dce c "toString" false;
| TType(tt,tl) ->
if not (List.exists (fun t2 -> Type.fast_eq t t2) dce.ts_stack) then begin
dce.ts_stack <- t :: dce.ts_stack;
to_string dce (apply_params tt.t_params tl tt.t_type)
end
| TAbstract({a_impl = Some c} as a,tl) ->
if Meta.has Meta.CoreType a.a_meta then
field dce c "toString" false
else
to_string dce (Abstract.get_underlying_type a tl)
| TMono r ->
(match !r with
| Some t -> to_string dce t
| _ -> ())
| TLazy f ->
to_string dce (!f())
| TDynamic t ->
if t == t_dynamic then
()
else
to_string dce t
| TEnum _ | TFun _ | TAnon _ | TAbstract({a_impl = None},_) ->
(* if we to_string these it does not imply that we need all its sub-types *)
()
and field dce c n stat =
let find_field n =
if n = "new" then match c.cl_constructor with
| None -> raise Not_found
| Some cf -> cf
else PMap.find n (if stat then c.cl_statics else c.cl_fields)
in
(try
let cf = find_field n in
mark_field dce c cf stat;
with Not_found -> try
if c.cl_interface then begin
let rec loop cl = match cl with
| [] -> raise Not_found
| (c,_) :: cl ->
try field dce c n stat with Not_found -> loop cl
in
loop c.cl_implements
end else match c.cl_super with Some (csup,_) -> field dce csup n stat | None -> raise Not_found
with Not_found -> try
match c.cl_kind with
| KTypeParameter tl ->
let rec loop tl = match tl with
| [] -> raise Not_found
| TInst(c,_) :: cl ->
(try field dce c n stat with Not_found -> loop cl)
| t :: tl ->
loop tl
in
loop tl
| _ -> raise Not_found
with Not_found ->
if dce.debug then prerr_endline ("[DCE] Field " ^ n ^ " not found on " ^ (s_type_path c.cl_path)) else ())
and mark_directly_used_class c =
if not (Meta.has Meta.DirectlyUsed c.cl_meta) then
c.cl_meta <- (Meta.DirectlyUsed,[],c.cl_pos) :: c.cl_meta
and mark_directly_used_enum e =
if not (Meta.has Meta.DirectlyUsed e.e_meta) then
e.e_meta <- (Meta.DirectlyUsed,[],e.e_pos) :: e.e_meta
and mark_directly_used_mt mt =
match mt with
| TClassDecl c ->
mark_directly_used_class c
| TEnumDecl e ->
mark_directly_used_enum e
| _ ->
()
and check_dynamic_write dce fa =
let n = field_name fa in
check_and_add_feature dce ("dynamic_write");
check_and_add_feature dce ("dynamic_write." ^ n)
and check_anon_optional_write dce fa =
let n = field_name fa in
check_and_add_feature dce ("anon_optional_write");
check_and_add_feature dce ("anon_optional_write." ^ n)
and check_anon_write dce fa =
let n = field_name fa in
check_and_add_feature dce ("anon_write");
check_and_add_feature dce ("anon_write." ^ n)
and is_array t = match follow t with
| TAbstract(a,tl) when not (Meta.has Meta.CoreType a.a_meta) -> is_array (Abstract.get_underlying_type a tl)
| TInst({ cl_path = ([], "Array")},_) -> true
| _ -> false
and is_dynamic t = match follow t with
| TAbstract(a,tl) when not (Meta.has Meta.CoreType a.a_meta) -> is_dynamic (Abstract.get_underlying_type a tl)
| TDynamic _ -> true
| _ -> false
and is_string t = match follow t with
| TAbstract(a,tl) when not (Meta.has Meta.CoreType a.a_meta) -> is_string (Abstract.get_underlying_type a tl)
| TInst( { cl_path = ([], "String")}, _) -> true
| _ -> false
and is_const_string e = match e.eexpr with
| TConst(TString(_)) -> true
| _ -> false
and expr dce e =
mark_t dce e.epos e.etype;
match e.eexpr with
| TNew(c,pl,el) ->
mark_class dce c;
mark_directly_used_class c;
field dce c "new" false;
List.iter (expr dce) el;
List.iter (mark_t dce e.epos) pl;
| TVar (v,e1) ->
opt (expr dce) e1;
mark_t dce e.epos v.v_type;
| TCast(e, Some mt) ->
check_feature dce "typed_cast";
mark_mt dce mt;
mark_directly_used_mt mt;
expr dce e;
| TObjectDecl(vl) ->
check_and_add_feature dce "has_anon";
List.iter (fun (_,e) -> expr dce e) vl;
| TTypeExpr mt ->
mark_mt dce mt;
mark_directly_used_mt mt;
| TTry(e, vl) ->
expr dce e;
List.iter (fun (v,e) ->
if v.v_type != t_dynamic then check_feature dce "typed_catch";
expr dce e;
mark_t dce e.epos v.v_type;
) vl;
| TCall ({eexpr = TLocal ({v_name = "`trace"})},[p;{ eexpr = TObjectDecl(v)}]) ->
check_and_add_feature dce "has_anon_trace";
List.iter (fun (_,e) -> expr dce e) v;
expr dce p;
| TCall ({eexpr = TLocal ({v_name = "__define_feature__"})},[{eexpr = TConst (TString ft)};e]) ->
Hashtbl.replace dce.curclass.cl_module.m_extra.m_features ft true;
check_feature dce ft;
expr dce e;
(* keep toString method when the class is argument to Std.string or haxe.Log.trace *)
| TCall ({eexpr = TField({eexpr = TTypeExpr (TClassDecl ({cl_path = (["haxe"],"Log")} as c))},FStatic (_,{cf_name="trace"}))} as ef, ((e2 :: el) as args))
| TCall ({eexpr = TField({eexpr = TTypeExpr (TClassDecl ({cl_path = ([],"Std")} as c))},FStatic (_,{cf_name="string"}))} as ef, ((e2 :: el) as args)) ->
mark_class dce c;
to_string dce e2.etype;
begin match el with
| [{eexpr = TObjectDecl fl}] ->
begin try
begin match List.assoc "customParams" fl with
| {eexpr = TArrayDecl el} ->
List.iter (fun e -> to_string dce e.etype) el
| _ ->
()
end
with Not_found ->
()
end
| _ ->
()
end;
expr dce ef;
List.iter (expr dce) args;
| TCall ({eexpr = TConst TSuper} as e,el) ->
mark_t dce e.epos e.etype;
List.iter (expr dce) el;
| TBinop(OpAdd,e1,e2) when is_dynamic e1.etype || is_dynamic e2.etype ->
check_and_add_feature dce "add_dynamic";
expr dce e1;
expr dce e2;
| TBinop( (OpAdd | (OpAssignOp OpAdd)),e1,e2) when ((is_string e1.etype || is_string e2.etype) && not ( is_const_string e1 && is_const_string e2)) ->
check_and_add_feature dce "unsafe_string_concat";
expr dce e1;
expr dce e2;
| TArray(({etype = TDynamic t} as e1),e2) when t == t_dynamic ->
check_and_add_feature dce "dynamic_array_read";
expr dce e1;
expr dce e2;
| TBinop( (OpAssign | OpAssignOp _), ({eexpr = TArray({etype = TDynamic t},_)} as e1), e2) when t == t_dynamic ->
check_and_add_feature dce "dynamic_array_write";
expr dce e1;
expr dce e2;
| TArray(({etype = t} as e1),e2) when is_array t ->
check_and_add_feature dce "array_read";
expr dce e1;
expr dce e2;
| TBinop( (OpAssign | OpAssignOp _), ({eexpr = TArray({etype = t},_)} as e1), e2) when is_array t ->
check_and_add_feature dce "array_write";
expr dce e1;
expr dce e2;
| TBinop(OpAssign,({eexpr = TField(_,(FDynamic _ as fa) )} as e1),e2) ->
check_dynamic_write dce fa;
expr dce e1;
expr dce e2;
| TBinop(OpAssign,({eexpr = TField(_,(FAnon cf as fa) )} as e1),e2) ->
if Meta.has Meta.Optional cf.cf_meta then
check_anon_optional_write dce fa
else
check_anon_write dce fa;
expr dce e1;
expr dce e2;
| TBinop(OpAssignOp op,({eexpr = TField(_,(FDynamic _ as fa) )} as e1),e2) ->
check_dynamic_write dce fa;
expr dce e1;
expr dce e2;
| TBinop(OpAssignOp op,({eexpr = TField(_,(FAnon cf as fa) )} as e1),e2) ->
if Meta.has Meta.Optional cf.cf_meta then
check_anon_optional_write dce fa
else
check_anon_write dce fa;
expr dce e1;
expr dce e2;
| TBinop(OpEq,({ etype = t1} as e1), ({ etype = t2} as e2) ) when is_dynamic t1 || is_dynamic t2 ->
check_and_add_feature dce "dynamic_binop_==";
expr dce e1;
expr dce e2;
| TBinop(OpEq,({ etype = t1} as e1), ({ etype = t2} as e2) ) when is_dynamic t1 || is_dynamic t2 ->
check_and_add_feature dce "dynamic_binop_!=";
expr dce e1;
expr dce e2;
| TBinop(OpMod,e1,e2) ->
check_and_add_feature dce "binop_%";
expr dce e1;
expr dce e2;
| TBinop(OpUShr,e1,e2) ->
check_and_add_feature dce "binop_>>>";
expr dce e1;
expr dce e2;
| TField(e,fa) ->
begin match fa with
| FStatic(c,cf) ->
mark_class dce c;
mark_field dce c cf true;
| FInstance(c,_,cf) ->
mark_class dce c;
mark_field dce c cf false;
| _ ->
let n = field_name fa in
(match fa with
| FAnon cf ->
if Meta.has Meta.Optional cf.cf_meta then begin
check_and_add_feature dce "anon_optional_read";
check_and_add_feature dce ("anon_optional_read." ^ n);
end else begin
check_and_add_feature dce "anon_read";
check_and_add_feature dce ("anon_read." ^ n);
end
| FDynamic _ ->
check_and_add_feature dce "dynamic_read";
check_and_add_feature dce ("dynamic_read." ^ n);
| _ -> ());
begin match follow e.etype with
| TInst(c,_) ->
mark_class dce c;
field dce c n false;
| TAnon a ->
(match !(a.a_status) with
| Statics c ->
mark_class dce c;
field dce c n true;
| _ -> ())
| _ -> ()
end;
end;
expr dce e;
| TThrow e ->
check_and_add_feature dce "has_throw";
to_string dce e.etype;
expr dce e
| _ ->
Type.iter (expr dce) e
let fix_accessors com =
List.iter (fun mt -> match mt with
| (TClassDecl c) ->
let rec has_accessor c n stat =
PMap.mem n (if stat then c.cl_statics else c.cl_fields)
|| match c.cl_super with Some (csup,_) -> has_accessor csup n stat | None -> false
in
let check_prop stat cf =
(match cf.cf_kind with
| Var {v_read = AccCall; v_write = a} ->
let s = "get_" ^ cf.cf_name in
cf.cf_kind <- Var {v_read = if has_accessor c s stat then AccCall else AccNever; v_write = a}
| _ -> ());
(match cf.cf_kind with
| Var {v_write = AccCall; v_read = a} ->
let s = "set_" ^ cf.cf_name in
cf.cf_kind <- Var {v_write = if has_accessor c s stat then AccCall else AccNever; v_read = a}
| _ -> ())
in
List.iter (check_prop true) c.cl_ordered_statics;
List.iter (check_prop false) c.cl_ordered_fields;
| _ -> ()
) com.types
let run com main full =
let dce = {
com = com;
full = full;
std_dirs = if full then [] else List.map Common.unique_full_path com.std_path;
debug = Common.defined com Define.DceDebug;
added_fields = [];
follow_expr = expr;
marked_fields = [];
marked_maybe_fields = [];
t_stack = [];
ts_stack = [];
features = Hashtbl.create 0;
curclass = null_class;
} in
begin match main with
| Some {eexpr = TCall({eexpr = TField(e,(FStatic(c,cf)))},_)} ->
cf.cf_meta <- (Meta.Keep,[],cf.cf_pos) :: cf.cf_meta
| _ ->
()
end;
List.iter (fun m ->
List.iter (fun (s,v) ->
if Hashtbl.mem dce.features s then Hashtbl.replace dce.features s (v :: Hashtbl.find dce.features s)
else Hashtbl.add dce.features s [v]
) m.m_extra.m_if_feature;
) com.modules;
(* first step: get all entry points, which is the main method and all class methods which are marked with @:keep *)
List.iter (fun t -> match t with
| TClassDecl c ->
let keep_class = keep_whole_class dce c && (not c.cl_extern || c.cl_interface) in
let loop stat cf =
if keep_class || keep_field dce cf then mark_field dce c cf stat
in
List.iter (loop true) c.cl_ordered_statics;
List.iter (loop false) c.cl_ordered_fields;
begin match c.cl_constructor with
| Some cf -> loop false cf
| None -> ()
end;
begin match c.cl_init with
| Some e when keep_class || Meta.has Meta.KeepInit c.cl_meta ->
(* create a fake field to deal with our internal logic (issue #3286) *)
let cf = mk_field "__init__" e.etype e.epos in
cf.cf_expr <- Some e;
loop true cf
| _ ->
()
end;
| TEnumDecl en when keep_whole_enum dce en ->
mark_enum dce en
| _ ->
()
) com.types;
if dce.debug then begin
List.iter (fun (c,cf,_) -> match cf.cf_expr with
| None -> ()
| Some _ -> print_endline ("[DCE] Entry point: " ^ (s_type_path c.cl_path) ^ "." ^ cf.cf_name)
) dce.added_fields;
end;
(* second step: initiate DCE passes and keep going until no new fields were added *)
let rec loop () =
match dce.added_fields with
| [] -> ()
| cfl ->
dce.added_fields <- [];
(* extend to dependent (= overriding/implementing) class fields *)
List.iter (fun (c,cf,stat) -> mark_dependent_fields dce c cf.cf_name stat) cfl;
(* mark fields as used *)
List.iter (fun (c,cf,stat) ->
if not (is_extern_field cf) then mark_class dce c;
mark_field dce c cf stat;
mark_t dce cf.cf_pos cf.cf_type
) cfl;
(* follow expressions to new types/fields *)
List.iter (fun (c,cf,_) ->
dce.curclass <- c;
opt (expr dce) cf.cf_expr;
List.iter (fun cf -> if cf.cf_expr <> None then opt (expr dce) cf.cf_expr) cf.cf_overloads
) cfl;
loop ()
in
loop ();
(* third step: filter types *)
let rec loop acc types =
match types with
| (TClassDecl c) as mt :: l when keep_whole_class dce c ->
loop (mt :: acc) l
| (TClassDecl c) as mt :: l ->
let check_property cf stat =
let add_accessor_metadata cf =
if not (Meta.has Meta.Accessor cf.cf_meta) then cf.cf_meta <- (Meta.Accessor,[],c.cl_pos) :: cf.cf_meta
in
begin match cf.cf_kind with
| Var {v_read = AccCall} ->
begin try
add_accessor_metadata (PMap.find ("get_" ^ cf.cf_name) (if stat then c.cl_statics else c.cl_fields))
with Not_found ->
()
end
| _ ->
()
end;
begin match cf.cf_kind with
| Var {v_write = AccCall} ->
begin try
add_accessor_metadata (PMap.find ("set_" ^ cf.cf_name) (if stat then c.cl_statics else c.cl_fields))
with Not_found ->
()
end
| _ ->
()
end;
in
(* add :keep so subsequent filter calls do not process class fields again *)
c.cl_meta <- (Meta.Keep,[],c.cl_pos) :: c.cl_meta;
c.cl_ordered_statics <- List.filter (fun cf ->
let b = keep_field dce cf in
if not b then begin
if dce.debug then print_endline ("[DCE] Removed field " ^ (s_type_path c.cl_path) ^ "." ^ (cf.cf_name));
check_property cf true;
c.cl_statics <- PMap.remove cf.cf_name c.cl_statics;
end;
b
) c.cl_ordered_statics;
c.cl_ordered_fields <- List.filter (fun cf ->
let b = keep_field dce cf in
if not b then begin
if dce.debug then print_endline ("[DCE] Removed field " ^ (s_type_path c.cl_path) ^ "." ^ (cf.cf_name));
check_property cf false;
c.cl_fields <- PMap.remove cf.cf_name c.cl_fields;
end;
b
) c.cl_ordered_fields;
(match c.cl_constructor with Some cf when not (keep_field dce cf) -> c.cl_constructor <- None | _ -> ());
let inef cf = not (is_extern_field cf) in
let has_non_extern_fields = List.exists inef c.cl_ordered_fields || List.exists inef c.cl_ordered_statics in
(* we keep a class if it was used or has a used field *)
if Meta.has Meta.Used c.cl_meta || has_non_extern_fields then loop (mt :: acc) l else begin
(match c.cl_init with
| Some f when Meta.has Meta.KeepInit c.cl_meta ->
(* it means that we only need the __init__ block *)
c.cl_extern <- true;
loop (mt :: acc) l
| _ ->
if dce.debug then print_endline ("[DCE] Removed class " ^ (s_type_path c.cl_path));
loop acc l)
end
| (TEnumDecl en) as mt :: l when Meta.has Meta.Used en.e_meta || en.e_extern || keep_whole_enum dce en ->
loop (mt :: acc) l
| TEnumDecl e :: l ->
if dce.debug then print_endline ("[DCE] Removed enum " ^ (s_type_path e.e_path));
loop acc l
| mt :: l ->
loop (mt :: acc) l
| [] ->
acc
in
com.types <- loop [] (List.rev com.types);
(* extra step to adjust properties that had accessors removed (required for Php and Cpp) *)
fix_accessors com;
(* remove "override" from fields that do not override anything anymore *)
List.iter (fun mt -> match mt with
| TClassDecl c ->
c.cl_overrides <- List.filter (fun s ->
let rec loop c =
match c.cl_super with
| Some (csup,_) when PMap.mem s.cf_name csup.cl_fields -> true
| Some (csup,_) -> loop csup
| None -> false
in
loop c
) c.cl_overrides;
| _ -> ()
) com.types;
(* mark extern classes as really used if they are extended by non-extern ones *)
List.iter (function
| TClassDecl ({cl_extern = false; cl_super = Some ({cl_extern = true} as csup, _)}) ->
mark_directly_used_class csup
| TClassDecl ({cl_extern = false} as c) when c.cl_implements <> [] ->
List.iter (fun (iface,_) -> if (iface.cl_extern) then mark_directly_used_class iface) c.cl_implements;
| _ -> ()
) com.types;
(* cleanup added fields metadata - compatibility with compilation server *)
let rec remove_meta m = function
| [] -> []
| (m2,_,_) :: l when m = m2 -> l
| x :: l -> x :: remove_meta m l
in
List.iter (fun cf -> cf.cf_meta <- remove_meta Meta.Used cf.cf_meta) dce.marked_fields;
List.iter (fun cf -> cf.cf_meta <- remove_meta Meta.MaybeUsed cf.cf_meta) dce.marked_maybe_fields;
haxe_3.2.1+dfsg.orig/extra/CHANGES.txt 0000664 0001750 0001750 00000221402 12607337712 017261 0 ustar andy andy 0000000 0000000 2015-10-11: 3.2.1
Bugfixes:
cs/java : fixed `-dce no` issues
cs/java : fixed how KExpr type parameters are generated
cs : fixed enum creation by reflection problem
cpp : do not rely in reflection to make interfaces work for non-first interface parents
cpp : fixed setting of static variables via reflection when class has no member variables
cpp : make sure StringMap's h field is kept if we use StringMap
js : Avoid the use of `eval`/`Function` to get the top-level defined type/var to not break ContentSecurityPolicy
2015-05-12: 3.2.0
New features:
all : added @:noPrivateAccess to re-enable access restrictions within @:privateAccess
cpp : some support for @:nativeGen metadata
Bugfixes:
all : fixed detection of @:generic classes with constructor constraints
all : fixed variable initialization check issue in loop condition
all : fixed pattern matching on @:enum abstracts via field access (#4084)
all : fixed missing implicit casts in Map literals (#4100)
all : fixed various minor issues in haxe.xml.Parser
all : fixed class path issue when HAXE_STD_PATH is set (#4163)
js : fixed DCE issue related to printing enums (#4197)
js : fixed various issues with the new Bytes implementation
php : fixed EOF handling in FileInput.readByte (#4082)
cs/java : fixed Math.fround implementation (#4177)
cs/java : fixed some cases of Std.parseInt failing (#4132)
cpp : fixed compilation without -main (#4199)
General improvements and optimizations:
all : --macro keep no longer causes types to be included for compilation
php : support interpolation in __php__ code
js : added variable number of arguments support in js.html.* classes
js : refined new HTML externs
Macro features and changes:
macro : [breaking] synced FClosure and FInstance with the compiler updates
2015-03-15: 3.2.0-RC1
This release removes support for Flash 8 target
New features:
all : added --display mode for toplevel completion
all : added --display mode for position and usage information
all : allowed @:callable on abstracts to forward calls to their underlying type
all : allowed pattern matching on getters
all : allowed @:native on class fields
all : added static analyzer with constant propagation
all : added Haxe-based XML implementation
python : added python target
flash : flash player 12-14 support
js : added @:jsRequire and js.Lib.require
js : support haxe.CallStack.exceptionStack
cs : added @:bridgeProperties
cs : added -D erase_generics
cs : added -D dll_import to import haxe-generated dlls
java/cs : added `sys.db` package
java/cs : clean unused files in output folder, unless `-D keep_old_output` is defined
java/cs : added `-c-arg` to add C#/Java compiler arguments
cpp : inititial implementation of cppia scripting
Bugfixes:
all : fixed nullability of abstracts over functions
all : fixed some equality checks between UInt and Int
all : fixed rare issue with abstract casts
all : fixed some internal code which relied on unspecified evaluation order
all : fixed exhaustiveness checks involving guards
all : fixed issue involving recursively constrained type parameters and @:generic
all : fixed type inference issue in map literals
all : fixed type inference issue when calling abstract method from within the abstract
all : fixed several abstract variance issues
all : fixed DCE issues with interface properties
all : fixed variance issue with function variables and dynamic methods on interfaces
all : fixed pattern matching on empty arrays that are typed as Dynamic
all : fixed various @:generic issues
all : fixed default cases on @:enum abstract being omitted
all : fixed various expression positions
all : disallowed break/continue in closures in loops
all : disallowed inline functions in value places
all : fixed parsing of cast followed by parentheses
all : fixed resource naming in case of invalid file system characters
all : fixed issue with inlined array declarations with field access
cpp : fixed issue with the side-effect handler
cpp : fixed issue with NativeArray in --no-inline mode
php : fixed issue with invalid references for closures in for-loops
php : fixed Reflect.compare and string comparison for numeric strings
cs/java : fixed various issues with -java-lib and -net-lib.
cs/java : added @:libType to skip checking on -java-lib / -net-lib types
cs/java : compilation server now works with C#/Java [experimental support]
cs : fixed Type.enumIndex / switch on C# native enums
cs : fixed reflection on COM types
java : fixed sys.net.Socket server implementation
spod : various fixes - working now on cpp, java, neko, php and c#
cpp : improved boot order, with enums constants first
General improvements and optimizations:
all : disallowed using `super` in value positions
all : check exhaustiveness of explicit Null types
all : resolve unqualified identifiers to @:enum abstract constructors
all : determine @:generic type parameters from constructor call if possible
all : properly disallowed field redefinition in extending interface
all : properly disallowed leading zeroes for Int and Float literals
all : allowed variance on interface variables
all : allowed pattern matching on arrays if they are typed as Dynamic
all : allowed pattern matching on fields of parent classes
all : -D doc-gen no longer implies -dce no
all : allowed matching against null on any enum instance
flash/js: optimized haxe.ds.StringMap
neko : create output directory if it does not exist
js : inline Math methods and fields
cs/java : optimized Reflect.fields on dynamic structures
cs/java : haxe will now clear output directory of old files (use -D keep-old-output to keep them)
cs : optimized field lookup structure
cs : optimized casting of parametrized types
cs : beautify c# code output
cs : added `cs.Flags` to manipulate C# enums that can be also flags
xml : improved documentation generation and fixed missing entity escaping
cpp : property access via Dynamic variables now requires property to be declared with @:nativeProperty
cpp : allow injection of code from relative paths using @:sourceFile and @:cppInclude
cpp : stronger typing of native functions via cpp.Function + cpp.Callable
cpp : moved 'Class' implementation to hx namespace to improve objective C interaction
cpp : added file_extension define to change the output filename extension (eg, ".mm")
cpp : added pre-calculated hashes to string constants to allow faster lookups
cpp : map implementation allows strongly typed interactions in some cases (avoids boxing)
cpp : added native WeakMap implementation
cpp : put each resource into own cpp file to allow more data/smaller files
Standard Library:
all : added typed arrays to haxe.io package
all : added haxe.ds.Either
all : added haxe.extern.Rest type for representing "rest" arguments in extern method signatures
all : added haxe.extern.EitherType abstract type for dealing with externs for dynamic targets
all : added haxe.DynamicAccess type for working with dynamic anonymous structures using a Map-like interface
all : [breaking] changed haxe.ds.Vector.get to return T instead of Null
all : added haxe.macro.Compiler.addGlobalMetadata
all : changed haxe.Int64 to be an abstract type instead of a class
js : updated HTML externs
Macro features and changes:
macro : added Context.getLocalTVars
macro : added TypedExprTools.iter
macro : added Context.getCallArguments
macro : changed @:genericBuild macros to prefer ComplexType returns
macro : [breaking] extended TAnonymous structures now have AExtend status instead of AClosed
macro : added Context.getDefines
macro : fixed file_seek from end (position was inversed)
macro : added Context.storeTypedExpr
macro : allowed type name reification
Deprecations:
all : deprecated structurally extending classes and interfaces
sys : Sys.command shell special chars (&|<>#;*?(){}$) are now properly escaped
java/cs : Lib.nativeType is now renamed to Lib.getNativeType
2014-04-13: 3.1.3
Bugfixes:
all : fixed handling of abstract variance
flash : ensure correct endianess in haxe.io.BytesBuffer
cpp : fixed issue involving class paths with spaces
php : fixed >>>
macro : fixed haxe.macro.Compiler.keep
General improvements and optimizations:
all : give @:deprecated warnings by default, allow -D no-deprecation-warnings
cpp : optimized Vector implementation
Standard Library:
all : renamed Bytes.readDouble/Float to getDouble/Float to avoid inheritance issues
all : deprecated Bytes.readString in favor of getString
all : added pretty-printing to haxe.format.JsonPrinter (and haxe.Json)
2014-03-29: 3.1.2
Bugfixes:
all : disallowed spaces between >>, >>>, >>= and >>>=
all : fix branching issue when switching on Dynamic values with only one case
all : added missing abstract cast call when checking for equality
all : fixed member fields initializations on parent classes that have no constructor
all : fixed toString usage of abstracts which are argument to Std.string
flash : avoid rare FP 12 PPAPI JIT crash
cpp : fixed bug in side-effect handler which caused incorrect behavior of while loops
js : fixed missing print function for enum values with DCE
macro : make sure member field initializations are respected
General improvements and optimizations:
all : cached file exist checks to speed up compilations with a lot of class paths
all : improved completion related to super class fields
all : allowed iterating on abstract which have get_length and @:arrayAccess fields
js : improved Type.allEnums implementation to avoid issues with obfuscation
Standard Library:
all : added haxe.io.Bytes.readDouble/Float
all : added haxe.io.BytesBuffer.addString/Float/Double
2014-03-15: 3.1.1
New features:
all : added -D deprecation-warnings
all : allowed \u escape sequences in strings
cs : implemented haxe.CallStack
Bugfixes:
all : fixed wrong handling of "" and null in haxe.io.Path.join
all : fixed invalid cast-to-self generation on some abstracts
all : removed @:to Dynamic from UInt to avoid issues in the Map selection algorithm
all : fixed various issues with UInt
all : fixed position setter in haxe.io.BytesInput
all : fixed various issues with member/static extension macros
flash : fixed invalid override involving single-constraint type parameters
flash8 : fixed various bugs
js : fixed a problem with Std.string(null) being optimized incorrectly
js : fixed custom generators
cpp : dealt with string literals that are too long for MSVC
cs : fixed various issues with -net-lib
2014-03-04: 3.1.0
New features:
all : allowed null-patterns in pattern matching
all : allowed extractors in pattern matching using => syntax
all : allowed extending generic type parameters
all : allowed (expr : type) syntax (ECheckType)
all : allowed @:enum and @:forward on abstracts
all : allowed using abstracts as static extension
all : allowed Class.new
all : added EnumValue.match
all : allow multiple structural extension using { > T1, > T2, fields }
all : inline array and structure declarations if possible
cs : added -net-lib
cs : support for native delegates
cs : support for attributes
cs : support for events
Standard Library:
all : support abstract types in haxe.rtti.XmlParser
all : added Std.instance
all : added length field to BytesBuffer, BytesOutput, BytesInput and StringBuf
all : added UInt for all targets
all : added Array.indexOf and Array.lastIndexOf
all : added haxe.xml.Printer
all : added haxe.Int32 as abstract type
all : added haxe.format.JsonParser/Printer
General improvements and optimizations:
all : optimized pattern matching output
all : allowed recursive type parameter constraints
all : improved support of custom @:coreType abstracts
all : evaluate conditional expressions in @:require
all : improved inline constructors by detecting more cases where it can be applied
js : improved inlining
js : always use JSON extern (compile with -D old-browser to disable)
js : added -D js-flatten
js : added -D js-es5
cpp : improved side-effect detection
Bugfixes:
all : inlining a parameter which has side effects will not remove it even if not used
all : implemented constraints check on enum and enum field type parameters
all : fixed memory leak in compilation server and optimized caching in general
all : fixed issue with invalid lowercase class name in Windows completion
flash : fixed font embedding with UTF8 chars
flash : give error if non-nullable basic types are skipped in a call
flash : give error if assigned parent class field values would be overwritten by super()
Macro features and changes:
macro : add Context.onAfterGenerate
macro : add Context.typeExpr
macro : add Context.getExpectedType
macro : add ExprTools.getValue
macro : allowed $v{(c:Float|Int|String)}
macro : resolve error line number in external files
macro : rewrote macros used as static extension
macro : exposed typed AST
macro : added @:genericBuild
macro : [breaking] first argument of ComplexType.TExtend is now Array instead of TypePath
macro : improved expression printing
2013-09-25: 3.0.1
all : minor DCE bug fix
2013-05-25: 3.0.0
all : added haxe.ds.BalancedTree
all : added haxe.ds.EnumValueMap
all : allow enum constructors as keys to Map
all : haxe.ds.ObjectMap is now correctly constrained on all targets
all : preliminary support of -D display-mode=usage|position|metadata
all : improved pattern matcher error messages
all : allow inline constructors
all : allow abstract member macros (not for @:op, @:arrayAccess, @:from, @:to)
all : allow abstract type parameter variance
all : do not generate hidden null on if without else
macro : made abstract structure available
2013-05-08: 3.0.0-RC2
all : improved abstract support
all : renamed HAXE_LIBRARY_PATH to HAXE_STD_PATH
all : added inlinable constructors
all : renamed haxe.ds.FastCell to GenericCell
all : fixed >= operator in #if conditionals
all : improved completion support for Unknown results
all : allowed [] access for Map
all : added haxe.ds.WeakMap (not yet supported on all platforms)
all : all trace parameters are now printed by default
all : added --help-metas
all : improved completion
all : improved pattern matching variable capture and GADT support
js : cached $bind results (unique closure creation per instance)
js : removed --js-modern (now as default)
cpp : added socket.setFastSend
flash : update player 11.7 api
flash : improved @:font, @:sound and @:bitmap support
neko/java/cs : improved Array performances when growing with []
java : added -java-lib support
java : added sys.net package implementation (alpha)
java : complete java std library through hxjava haxelib
java/cs : added support for overloaded function declarations
java/cs : overload selection algorithm
cs : operator overloading is now accessible through Haxe
cs : source mapping; can be disabled with -D real_position
as3 : fixed rare syntax ambiguity
php : removed initialization of some inline fields
macro : fixed several issues with 'using' a macro function
macro : improved expression printing
2013-02-24: 3.0.0-RC
flash : updated player 11.4 api
all : allowed named functions as r-value
all : fixed using + overload usage
all : allow any type constraint for type parameters
all : make property type optional (when a initial value is set)
all : Std.random(x) when x <= 0 is now always 0
spod : added serialized data with SData
all : Dispatcher will now throw DETooManyValues
all : speed up neko compilation by using native compiler
all : allow @:generic on functions
all : allow constructing generic type parameters
swf : added support for SWC files in -swf-lib
macro : added Context.onTypeNotFound callback for unresolved types
js : no JS embed as default (use -D embed-js instead)
all : added abstract types (Int/Float/Bool/Void/Class/Enum/EnumValue)
all : added --help-defines
all : changed DCE with three modes : std(default), no and full
all : Haxe3 packages changes (see http://haxe.org/manual/haxe3)
all : Removed haxe.Int32, haxe.Firebug, haxe.TimerQueue
all : added -D key=value and #if (key >= value) operations
all : StringTools.htmlEscape/unescape nows handle "/" and '/'
all : using and import must now appear before any type declaration in a file
all : no longer create variable fields for pure getter/setter properties (unless @:isVar is used)
all : use default get_prop/set_prop instead of custom getter/setter names for properties
js : added JQuery.delegateTarget
macro : removed EType and CType, added EMeta, modified ESwitch
all : allow @metadata expr
all : replaced haxe.rtti.Generic interface with @:generic metadata
all : no longer infer arrays of mixed types as Array
all : all type/import/enum constructor resolution now follows the shadowing principle (latest has priority)
all : added EReg.matchSub, renamed EReg.customReplace to map
all : no longer allow initialization of extern non-inline variables
swf : fixed out of memory errors on very large swf-lib files
swf : added -D swf_preloader_frame, swf_gpu, swf_direct_blit
swf : added -D swf_script_timeout=seconds, swf_debug_password=password, swf_metadata=file
swf : added -swf-lib-extern
swf : added @:font support (beta)
all : added GADT support in enums
all : added pattern matching (beta)
all : changed callback(func, args) to func.bind(args)
macro : added haxe.macro.ExprTools/ComplexTypeTools/TypeTools
macro : changed reification syntax to ${expr}, $a{array}, $p{path}, $v{value}
macro : allow macro @:pos(pos-expr) to inject positions for reification
all : added array comprehension
flash : Vector.length is now Int instead of UInt
all : moved haxe.BaseCode, haxe.Md5 and haxe.SHA1 to haxe.crypto package
all : disallow Void variables and arguments (still allow S -> T to S -> Void)
all : added Array.map/filter
all : added spell check suggestions for enum constructors and fields
all : added opaque abstract(T) types
all : allow operator overloading on opaque abstract types
all : renamed IntIter to IntIterator
all : added Map
all : added haxe.ds with StringMap, IntMap, HashMap, ObjectMap, Vector, GenericStack
all : removed Hash, IntHash and haxe.FastList in favor of the types in haxe.ds
all : haxe.xml.Parser now handles entities consistently across platforms
all : renamed HAXE_LIBRARY_PATH environment variable to HAXE_STD_PATH
2012-07-16: 2.10
java/cs : added two new targets (beta)
all : fixed List and Null for first, last, pop
js : added js.Lib.debug()
flash : fixed Xml.parent() when no parent
flash : fixed haxe.io.Bytes.blit when len=0
js/php/flash8 : fixed haxe.Int32.mul overflow on 52 bits
js : fixed haxe.Utf8 usage (static 'length' issue)
all : does not allow overriding var/prop
flash : removed wrapping for Xml nodes, use instead specific compare when comparing two typed nodes
js : use new haxe.xml.Parser (faster, not based on Regexp)
flash : fixed completion issue with for( x in Vector )
all : optimized Std.int(123) and Std.int(123.45)
flash : bugfix for @:bitmap with 24-bits PNG (flash decode wrong colors)
as3 : fixed EnumValue becomes Object
js : removed js.Lib.isIE/isOpera (not complete, use js.JQuery.browser instead)
all : function parameters are nullable if they are declared with '?'
all : added support for finding common base types of multiple types (unify_min) for array, switch, if
php : do not implement duplicate interfaces
haxelib : added git support through haxelib git
all : allow derived classes to widen method visibility
macro : added haxe.macro.Context.getLocalMethod
macro : improved support of "using" macro functions
php : optimized Xml implementation
php : fixed Reflect.get/setProperty not working on PHP < 5.3
all : support for callback(f, _, x)
all : allow private access between classes that have a common base class
all : added Output.writeFloat/Double and Input.readFloat/Double
all : support for var:{x:Float} = { x = 1 } constant structure subtyping
all : allow contravariant function arguments and covariant function returns in overrides
macro : support for final Array argument as rest argument
macro : use top-down inference on macro calls
all : made "using" imply "import"
all : made String concat more consistent across platforms (add Std.string wrappers)
all : allow direct member variable/property and static property initialization
js : greatly reduced amount of generated code by using smarter DCE
php : made modulo operations more consistent
all : allow local functions to have both type parameters and be inlined
all : functions type parameters can be constraint (will be checked at end of compilation)
macro : use NekoVM runtime for regexps, process and xml parsing
flash : allow @:getter/@:setter in interfaces
flash : added support for "arguments" in methods
all : not used enums and inline var/methods are now removed by DCE
all : allow @:overload to use type parameters and not-absolute type paths
all : ensure that Std.string of arrays and enums are now consistent across platforms
all : allow to inline functions containing other functions
xml : added metadata output to xml generator
macro : added macro and macro : reification
all : renamed type(e) to $type(e)
as3 : support for metadata and resources, and other fixes
2012-04-14: 2.09
all : optimized const == const and const != const (with different const types)
all : add Type.allEnums(e)
all : big improvements with completion speed and fixed many issues
flash9 : fixed -D swfprotected with swc output
neko : added ~ implementation
js : upgraded jquery version, more api overloads
sys : added "in" operator for spod macros, added relation access in expressions
macro : added ECheckType
macro : added TLazy for not-yet-typed class fields
js/php/neko : added haxe.web.Request
all : added Std.format
js : trace() output fallback on console.log if no id="haxe:trace"
all : ensure that Std.is(2.0,Int) returns true on all platforms
js : replaced $closure by function.$bind + changes in output format
all : allowed @:extern on static methods (no generate + no closure + force inlining)
all : added documentation in --display infos + display overloads in completion
js : removed --js-namespace, added $hxClasses
flash : output traces to native trace() when using -D fdb or -D nativeTrace
all : allowed abitrary string fields in anonymous objects
all : allowed optional structure fields (for constant structs)
all : allowed optional args in functions types (?Int -> Void)
all : added Reflect.getProperty/setProperty (except flash8)
all : added --wait and --cwd and --connect (parsed files and module caching)
all : fixed completion in macros calls arguments
all : fixed DCE removing empty but still used interfaces/superclasses
all : added haxe.Utf8 (crossplatform)
neko : Reflect now uses $fasthash (require neko 1.8.2)
all : allow \uXXXX in regexp (although not supported everywhere)
js : make difference between values and statements expressions in JSGenApi
js : added source mapping with -debug (replace previous stack emulation)
flash : added @:file("a.dat") class File extends flash.utils.ByteArray
flash : added @:sound("file.wav|mp3") class S extends flash.media.Sound
js : added --js-modern for wrapping output in a closure and ES5 strict mode
all : null, true and false are now keywords
all : neko.io.Path, cpp.io.Path and php.io.Path are now haxe.io.Path
neko, cpp, php : added Sys class, sys.io and sys.net packages and "sys" define
all : allow to access root package with std prefix (std.Type for example)
all : added haxe.EnumFlags
sys : io.File.getChar/stdin/stdout/stderr are now in Sys class
cpp : Reflect.getField and Reflect.setField no longer call property functions. Use Reflect.getProperty and Refelect.setProperty instead.
cpp : Default arguments now use Null for performance increase and interface compatibility
cpp : Added metadata options for injecting native cpp code into headers, classes and functions
php : added php.Lib.mail
(hotfix) fixed bug in completion and disabled profiling on Linux
(hotfix) fixed $ssize when doing new String(v) in neko
(hotfix) fixed bug with properties in interfaces for Flash & PHP
2011-09-25: 2.08
js : added js.JQuery
all : added @:overload
js : upgraded js.SWFObject from 1.4.4 inlined to 1.5 embedded
js : code generator beautify
all : ensure that modifying returned Type.getEnumConstructs array does not affect enum
all : allow macro typed parameters (other than Expr)
flash : added flash11 apis
neko : added support for https to haxe.Http (using hxssl library)
all : added haxe.Int64
all : added haxe.Int32 isNeg,isZero,ucompare, fixed overflows for js/flash8/php
all : bugfix when optimizing inlined immediate function call
all : fixed "using" on macro function
all : allowed member macros functions (called as static)
neko : allowed serialization of haxe.Int32 (as Int)
all : fixed invalid optimization of two constant numbers comparison
flash8 : bugfix Std.parseInt with some hex values
flash9 : added flash.utils.RegExp
all : changed @:build behavior, now takes/returns a var with anonymous fields
all : added @:native support for enums
neko : changed the result of array-assign expression (was null)
flash9 : no longer auto create enums from SWF classes
(need explicit "enum" type patch)
all : optimized variable tracking/renaming
all : optimized macro engine (speed x2)
all : added -D macrotimes support
flash9 : store resources in bytes tag instead of bytecode
all : allow $ prefixed identifiers (for macros usage only)
all : allow to access modules subtype statics with pack.Mod.Type.value
and fixed identifier resolution order
flash9 : added @:bitmap("file") for simple embedding
all : added haxe.web.Dispatch
js : added js.Storage
all : allow this + member variables access in local functions
added untyped __this__ support and transition error
all : added haxe.macro.MacroType
neko : neko.Lib.serialize/unserialize now returns bytes
neko : added sys.db package (crossplatform with -D spod_macro support)
spod_macro now uses wrappers for Bytes (require neko 1.8.2)
php : added --php-prefix for prefixing generated files and class names
all : added type_expr_with_type enum support
php/js : fixed adding 'null' to StringBuf
all : added haxe.macro.Context.defineType
2011-01-30: 2.07
all : fixed completion support with --remap
all : added macros, added --interp
all : removed 'here' special identifier
neko : fixed neko.Web.getParamsString() returning "null" instead of ""
flash9 : fixed issue with @:bind
flash9 : added some missing errors
flash9 : fixed TypedDictionary.exists
all : added @:build and @:autoBuild for enums and classes
neko : Std.parseFloat now returns NaN with invalid string
php: fixed Array.push must return the current length (issue 219)
php: fixed EReg.replace (issue 194)
php: FileSystem.readDirectory now skips '.' and '..' to be consistent with neko (issue 226)
flash9 : add trace text on stage (always over current and subclips)
flash9 : delay SWF initialization until it's added on stage and stageWidth > 0
(this can be disabled with -D dontWaitStage)
all : added haxe.Timer.measure
all : added Lambda.indexOf and Lambda.concat
all : no longer allow inline vars as metadata values
neko : added getFieldsNames to neko.db.ResultSet (supported in Neko 1.8.2 mysql driver)
all : added --macro and haxe.macro.Compiler
all : allow macro type patches
flash9 : changed --gen-hx-classes implementation
now use 'haxe -swf-lib lib.swf --gen-hx-classes' instead
flash9 : added @:getter and @:setter
all : added @:require
flash9 : moved vector utils functions from flash.Lib to flash.Vector
flash9 : added support for FP 10.1 and 10.2
flash9 : added @:meta(Meta(k="v")) support
all : improved #if support (fixed ! precedence)
all : lookup unqualified types in all package hierarchy and not only in current package
flash : set default flash version to 10 (-swf9 deprecated, use -swf-version 8 for avm1)
php : added --php-lib to allow to rename the destination path of the generated lib
all : added --dead-code-elimination, removes unused functions from the output
(beta feature could not make in the final release)
all : added @:keep to prevent --dead-code-elimination of class/method
flash9 : fixed issues with loading a Haxe SWF (boot_XXXX class extends flash.Boot)
all : allow to inline override methods (if the superclass method is not inlined already)
all : fixed escape sequences in literal regular expressions
flash9 : fixed Xml.setNodeValue
all : removed -excluded, replaced by --macro excludeFile('filename')
all : added --macro exclude('package') and --macro include('package')
all : importing a typedef of an enum allow to access its constructors
all : removed String.cca (replaced by StringTools.fastCodeAt + StringTools.isEOF)
flash9 : fixed use of default values when null is passed for nullable basic types
all : fixed issues with inlining and class/function type parameters
all : big speedup for compiler internal completion
all : added --macro keepClass('classname')
flash9 : fixed Xml.nodeValue for comments (does not include )
all : added named local functions (allow self-recursion)
all : use left-assoc for (==,!=,>,>=,<,<=)(==,!=,>,>=,<,<=) (&&)(&&) and (||)(||)
all : give prefix unary operators higher priority than ?:
php : fixed XML parsing
cpp : many fixes
2010-08-14: 2.06
neko : change serializer to be able to handle instances of basic classes from other modules
js : add Document.createTextNode
all : bugfix with inline when modifying var with same name as one of current local
flash9 : classes implementing ArrayAccess are now dynamic (including TypedDictionary)
all : allow "using" on typedefs
as3 : minor fixes in genas3 and --gen-hx-classes
as3 : fix with readonly/writeonly properties accesses
flash9 : list native getter/setters in Type API class/instance fields
all : make haxe.rtti.Generic typing lazy (fix for self-recursion)
all : allow haxe.rtti.Generic + inheritance
all : added resource size limit to 12MB (ocaml max_string_size is 16MB + b64)
flash : changes in swf handling to work with >16MB swfs
flash9 : only init dynamic methods if not already defined (in subclass)
std : added haxe.SHA1
compiler : added TCast, allow cast optimization on flash9/cpp
as3 : fixed Std.__init__ generating 'null'
compiler : fixed -no-opt
flash : allow several -swf-lib
no longer support automatic creation of classes for f8 swfs in f9 mode
classes defined in f9 swf are not redefinable in Haxe code (use extern)
flash9 : allow direct access and completion with classes defined in -swf-lib's
flash9 : remove imported libraries debug infos when not compiled with -debug
all : only display errors with --display if no completion matched
all : some completion related errors fixed
flash9 : added @:bind support
all : fixed StringTools.hex with negative numbers
flash9 : fixed Type.typeof(1<<28) was TFloat
flash9 : use flash.XML parser for Xml class implementation
neko : fixed Array.splice (was not setting null at end of array)
neko : rewrote Array class using neko.NativeArray
all : core classes implementation are now in std/(platform)/_std
all : added @:final support
all : added haxe.rtti.Meta
flash9 : added flash.desktop.Clipboard* classes (added in flash10)
as3 : fixed Date.toString issue in flash.Boot (now use .toStringHX instead)
this will only work if .toString called explicitely on Date class
all : only allow "using" on Dynamic if first parameter is Dynamic
php : haxe.Http now supports Https connections when OpenSSL extension is enabled (issue 143)
php : fixed enum constructors sequence (issue 142)
php : added error message when using 2 fields with different cases in the same class/enum
php : fixed field declaration for properties with getter and setter (issue 124)
php : fixed comparison issues between strings (issue 132)
php : enhanced FileInput.readLine using native fgets function (issue 103)
flash9 : renamed flash.Error to flash.errors.Error
php : removed eval() everywhere and simplified _hx_lambda
php : fixed return type for Std.string() with integers and floats
php : fixed php.Lib.rethrow
all : added custom Haxe serialization
php : aligned php.Web.parseMultipart signature with neko implementation
cpp : Added source location and stack dump for errors in debug mode
cpp : Remapped more keywords
cpp : Added templated fast iterator code for arrays and FastLists
cpp : Added option for tracing GC references in debug mode
cpp : Switch the native string implementation from wchar_t to utf8 - for regex speed
cpp : Added extra "()" to ensure correct order of operations
cpp : Fixed various bugs for unusual (and not so unusual) language constructs
cpp : Fixed order of enum generation from index
cpp : Added __unsafe_get and __unsafe_set to Array as possible optimizations
cpp : Default to mult-thread compiling on windows for cl version >= 14
cpp : Seed Math.random
cpp : Use strftime for Dates
cpp : Fix socket sellect passing _s
cpp : Throw error when match count does not match regex
cpp : Improve register capture in GC
cpp : Fix Dynamic interger compare
cpp : Implement makeVarArgs
cpp : Fix toString for nulls in Enums and Arrays
cpp : Added initial Android support
cpp : Move initializers to entry functions in standard ndlls.
cpp : Changes some CFFI register funtions to char*, from wchar_t*
cpp : Added some initial support for v8 script target
cpp : Use non-recursive GC marking to avoid overflow in big lists
cpp : Added __hxcpp_obj_id
2010-01-09: 2.05
js : added js.Scroll
js : package names are now checked at runtime to avoid clashes with existing libs
js : added --js-namespace to create a namespace for types that are defined in the root
all : updated xml output and html doc - add inline, override, dynamic functions support
all : added error when comparing enum with arguments
all : optimize constant equality for enums
flash9 : fixed verify error with inline + null type
flash9 : bugfix when overriding/implementing an method with an applied type parameter
php : fixed issues with classes that implement Dynamic
all : ignore #! line at beginning of the hx file
haxelib : added tags, added documentation
flash8 : don't use b64 encoding for text ressources
php : fixed bug in Hash.exists for null values and Reflect.callMethod
js/flash9 : throw exception in Xml.parse when unclosed node
all : improve return type progagation in inlined expression (fix some VerifyErrors)
all : optimize {const} into const
all : added structure / Dynamic subtyping
all : fixed List.map2 error when inline + optional args
flash9 : encode all ISO constant strings into UTF8 at compilation time
all : allow hxml with only -cmd statements
spod : moved Manager.addQuote to Connection.addValue
flash9 : removed .iterator() from Vector (not implementable)
all : fixed haxe.rtti.Generic on interfaces
php : fixed issue with Reflect.callMethod
php : fixed issue with PHP reserved word used in callbacks
all : bugfix with non-constant enums in switches
flash9 : fix for interfaces (use namespace)
all : "using" now works for identifiers in member methods
flash9 : bugfix with switch on some big integers
all : bugfix when optimizing (function(x) return x)(x)
neko : improved speed of Xml.toString()
all : added -D dump (for debugging purposes)
neko : added neko.Web.isTora
php : added php.db.PDO (php.db.Sqlite is now deprecated)
php : fixed bug in Type.getClassFields() that reported duplicated entries
php : fixed errror in XML error reporting
all : allow sub-types declarations everywhere (pack.Type.Sub)
all : added completion for sub-types declarations
all : improved completion with lambda function
as3 : several generation fixes
all : bugfix haxe.rtti.Generic on private class
php/js/cpp : sanitize binary expressions to prevent inlining errors
spod : remove object from cache when deleted
2009-07-26: 2.04
flash9 : fixed get_full_path error with -D fdb
js : fixed Array.remove on IE
flash8 : removed extra empty AS3 tag (causing some issue with F8 loadMovie)
improved speed of Bytes unserializing (no need for BytesBuffer)
flash9 : bugfix, Null was generating dynamic code
flash9 : added error message in flash.Vector if used without flash 10
flash9 : fixed some "never" property access issues
all : added "never" property access support for all platforms
js : small syntax fix with value-blocks
js : fixed Type.enumEq with null values
js/flash8 : use &0xFF in haxe.io.Bytes.set
flash9 : fixed switch on Null verify error
flash9 : fixes related to UInt type + error when using Int/UInt comparison
as3 : improved Vector support, inline flash.Lib.as
as3 : bugfix with skip_constructor
as3 : added Enum.__constructs__ (allow Type.getEnumConstructs)
as3 : make all constructor parameters optional (allow Type.createEmptyInstance)
as3 : bugfix with property access inside setter (stack overflow)
all : Enum is now Enum
all : added Type.createEnumIndex
all : forbid same name for static+instance field (not supported on several platforms)
all : renamed haxe.Http.request to "requestUrl"
all : renamed neko.zip.Compress/Uncompress.run to "execute"
spod : fix very rare issue with relations and transactions
compiler : added TClosure - optimize closure creation and ease code generation
cpp : added CPP platform
all : added 'using' syntax
neko : added 'domains' optional param to ThreadRemotingServer to answer policy-file-request
php : fixed php.db.Mysql so that getResult is consistent with Neko behavior
php : fixed __toString for anonymouse objects
php : fixed bug in overridden dynamic functions
php : fixed round to be consistent with other platforms
php : fixed bug concatenating two dynamic variables
php : php.Lib.rethrow now works as expected
flash9 : fixed bug with SWC output and recursive types
flash8 : fixed inversed arguments in __new__
neko : added neko.net.Socket.setFastSend
php: fixed String.charCodeAt
php: minor optimization (removed foreach from std code)
php: implemented haxe.Stack
php: changed exception handler to use Haxe call stack
php: changed special vars to use the '\xBB' prefix instead of __
php: fixed use of reserved keywords for var names
php: List iterator is now class based (faster)
php: fixed behavior of class variables having assigned functions
php: fixed php.db.Manager (was uncorrectly removing superclass fields)
php: added support for native Iterator and IteratorAggregate interfaces
all : added --display classes and --display keywords
all : fixed issue with optional parameters in inline functions
all : allow implementing interfaces with inline methods
all : enable inlining for getter/setter/iterator/resolve/using
2009-03-22: 2.03
optimized Type.enumEq : use index instead of tag comparison for neko/flash9/php
bugfix for flash.display.BitmapDataChannel and GraphicsPathCommand (allow inline static)
resolve environment variable in -cmd commands
added flash.Vector.indexOf and lastIndexOf
fixed bug in interfaces that define the method toString (Haxe/PHP)
fixed bug in haxe.io.BytesInput.readBytes in Flash9 (was throwing Eof if full buffer can't be readed)
fixed implements/extends special classes when they are imported
StringBuf now uses an array for JS implementation (around same on FF, faster on IE)
fixed assignment of field length in anonym objects (Haxe/PHP)
fixed addEventListener typing for flash9
fixed __vector__ generation for AS3 target
fix with inline functions : position is now the inserted position and not the original one (better error reporting)
added SWC output support
fixed issues with unset of values in for loops and executing blocks that return functions (Haxe/PHP)
"throw" type is now Unknown instead of Dynamic (prevent type-hole in "if A else if B else throw")
added __foreach__ for flash9/as3
fixed f9 verify error with different kind of functions
moved eof() from neko.io.FileOutput to FileInput
added haxe.rtti.HtmlEditor
added neko.db.Manager.setLockMode
genAS3 : fixed Error classes issues
genAS3 : fixed default basic type value in interfaces
flash9 : fixed UInt default parameter verify error
flash9 : fixed issue with flash.* string enums verify error
compiler : allowed \r line separators for HXML files
flash9 : fixed verify error with loop variable beeing a specific class
compiler : prevent truncating float dynamic values to int when using numerical operations
neko.db.Manager fix : synchronize fields after locking an unlocked cached object
compiler : fixed issue with cascading inline+haxe.rtti.Generic
optimizer : reduce constant int/float/bool expressions and immediate function calls
flash9/as3/php : don't add Boot.skip_constructor test if no side effects in constructor
compiler : added --no-opt to disable expr reduction
compiler : separated basic and advanced commandline options
compiler : fixed printing of sub-function types
genHX : fixed generation of classes that extends another class (shouldn't be turned into enums)
speedup Array.remove on flash9/js
2008-11-23: 2.02
Std.is(MyInterface, Class) now returns true (Haxe/PHP)
php arrays are wrapped into _hx_array instances, fixes issues with references (array cast, access out of bounds ...)
removed untested php classes (php.DBase, php.IniHash)
added -D use_rtti_doc
flash.Lib.getTimer() now returns Int and is inlined
fixed php.FileSystem.stat
added memory related functions to php.Sys
added error when trying to extend Array, String, Date and Xml
fixed handling of implements ArrayAccess
fixed some minor things in flash10 api
switch/for/while/do/try/if are no longer using parse_next (parenthesises requ. instead)
fixed Type.typeof and Std.is in case of too much large integers for Flash6-8/JS
haxe.xml.Check : treat comments the same as PCDATA spaces
haxe.io.BytesData now uses strings instead of arrays for PHP
compiler : optimized line calculus from ast position
lexer : allow identifiers starting with _[0-9]
fixed access to flash.Vector methods : use AS3 namespace (faster)
bugfix in inline functions : modifying a parameter can't modify a real local var anymore
bugfix in inline functions : handle class type parameters and method type parameters
fixed issue with Int default value for Float parameter
flash9 : bugfix when using the retval after setting a closure variable
added flash.Memory API for flash10 alchemy opcodes access
changed #if as3gen to #if as3 when generating as3 code
fixed as3 flash.Vector generation
fixed haxe.io.BytesOutput for flash9 : set default to little-endian
some flash9 fixes related to extern enums
updated flash.text.engine package with haxe enums
flash9 : use target file path for Boot unique ID instead of random number
as3 : fixed bug when anonymous field was a reserved identifier
flash9 : added flash.Lib.vectorOfArray and vectorConvert for flash10
added -D check-js-packages to allow several haxe-generated js files in same page
2008-10-04: 2.01
fixed php.Sys
added neko.NativeString and neko.NativeArray
fixed php.Boot.__string_rec() when invoked from toString
fixed null references in class constructors for array arguments
fixed Type.enumParameters() and Type.typeOf() for PHP
fixed SPOD/MySql for PHP
fixed php.net.Socket.setTimeout(), php.io.Process
fixed php.Web.setCookie() for expire time
fixed php rethrow in catches and added the possibility to catch native exceptions
added runttime check for php.io.Socket.shutdown (uses fclose in php 5.1.x)
allowed optional Context in remoting connections
fixed extern classes for flash < 8
fixed inherited protected/private properties in as3 SWF library
fixed haxe.io float/double in Neko (when bigEndian was null)
added __FSCommand2__ support
optimized haxe.Unserializer (use faster buffer access)
use "Dynamic" instead of Dynamic->Void for flash9 IEventDispatcher
always use full classes paths for genAS3
prevent different get/set property accesses when implementing an interface
fixed assign of dynamicfunction references in PHP
Haxe/PHP now generates code for extern classes __init__
added strings literal support in haxe.Template
fixed Process arguments and exitCode() in Haxe/PHP
fixed hierarchy problem for classes with the name from different packages Haxe/PHP
php.db.Mysql now throws an exception when tries to connect to an unexistant DB
fixed blocks in if statements for Haxe/PHP
added php check on the full hierarchy for colliding names
added support for "g" modifier in EReg for PHP
PHP now generates __toString for classes that have toString defined
implemented php.Lib.getClasses()
fixed duplicate fields in Type.getInstanceFields on subclass
Enum is no longer defined inside Type but is standalone class
fixed Date.getDay on Neko/Windows (use %w instead of %u)
fixed memory leak with PHP closures
fixed wrong scope in PHP closures
fixed Array.reverse() in PHP
fixed Reflect.compareMethods in Neko (require Neko 1.8.0)
fixed flash7-8 register usage for __init__ and static variables initialization
moved StringTools.baseEncode/Decode to haxe.BaseCode
fixed binary resources for Flash, JS and PHP outputs
fixed compiler bug with inline + optional arguments
fixed Type.createInstance and createEmptyInstance with Array for flash6-8
2008-07-28: 2.0
fixed current package bug in inherited constructor type
delayed type-parameter constraints check (allow mutual rec extends for SPOD)
improved unclosed macro error reporting
Haxe/PHP integration
renamed NekoSocketConnection to SyncSocketConnection (php support)
fixes in genAs3
fix for flash9 : always coerce call return type
set all private+protected names from SWF lib to public (allow override+reflect)
flash9 : use findprop instead of findpropstrict for 'this' access (allow dynamic)
don't allow nullness changes in overrided/implemented
prevent typing hole with overriden polymorphic methods
added neko.vm.Mutex and neko.vm.Deque (included in neko 1.7.1)
added package remapping using --remap
2008-07-17: 2.0-RC1
genneko : remove big array error (fixed in neko 1.7.1)
fixed neko.net.ThreadRemotingServer.onXML
genswf9 : fixed verify error with Null (was using dynamic access)
small patch for jsfl support
added .cca for faster string operations on Flash9/Flash/JS
bugfix with inlined local variables
upgraded flash9 api to flex3/player 9.0.115
override is now mandatory, no more --override
dynamic is now a keyword
f9dynamic is now dynamic and is mandatory on all platforms
public/private/dynamic are inherited by default when overriding a method
removed Reflect.empty() : use {} instead
changed #else by #elseif, added #else
flash9 : optimized Hash,IntHash,StringBuf (use typed value)
Reflect.field/setField/callMethod , Type.enumIndex and StringBuf methods are now inlined
optimized haxe.Md5 : don't use statics
allow up to 8 parameters in Reflect.createInstance
flash9 : some minor optimizations in haxe.Serializer
added haxe.io package (removed things from neko.io)
__resolve becomes resolve (and should be documented)
added haxe.Int32
removed neko.Int32
removed neko.io.Input/Output/Eof/Error/Logger/Multiple/StringInput/StringOutput
removed neko.net.RemotingServer
changed neko apis to use haxe.io and Bytes instead of String buffers
fixed big bug in js/flash8 debug stack handling
complete rewrite of haxe.remoting package
haxe.io.Bytes serialization support (replace deprecated string support)
removed === and !==
removed Std.bool
fixed : Reflect.field(null) in flash9 doesn't throw an error anymore
removed Type.toClass and Type.toEnum
Dynamic type is now a class and not an enum
moved reflection support for core types from Boot to Std
fixed Type.getClassName/getEnumName/resolve for core flash9 types
renamed haxe.rtti.Type to haxe.rtti.CType (with changes in prefix)
added haxe.TimerQueue, added haxe.Timer.delay, remove haxe.Timer.delayed
flash9 : bugfix, generated interfaces were empty
fixed bug while writing block-vars in flash/js
added parameters default value (constants)
removed Std.resource, Std.ord, Std.chr
added haxe.Resource, allow binary data in resources
added Type.createEnum
check that local variables get correctly initialized before usage
haxe.Stack support for flash9
2008-04-05: 1.19
fixed flash9 Array.toString
fixed inline return bug
added haxe.rtti.Generic behavior
added haxe.FastList
bugfix to prevent recursive anonymous
fixed some incorrectly reported "recursive inline" errors
fixes in genas3 + genswf9 for Dynamic/* in methods
{} is now an empty object and not an empty block
fixed some verify errors left in flash9
fixed private/protected differences in gen-hx-classes
genswf9 : allowed to store a Class in a typed register
fixed switch-on-bool (don't use matching)
genswf9 : optimized switch on ints
some renames in haxe.rtti.Type
added flash.utils.TypedDictionary for F9
genswf9 : fixe debug filename with inline code
fixed completion for packages starting with 'a' or 'z'
added flash9.Lib.as
prevent double Movieclip class declaration when linking flash9 lib
allow numerical operations on type parameters constraint by Float
genswf9 : fixed dynamic inheritance
2008-02-23: 1.18
some optimization and bugfix for as3 codegen
bugfix : allow bitmaps and fonts classes for F9 library
bugfix : neko.Web.setCookie
bugfix : as3 switches in -swf-lib, and enable to "repair" corrupted as3 bytecode
fixed --i return value in flash9
fixed some transforms in flash9
added js.Selection
simplified js.Dom (more events)
added haxe.xml.Fast.innerHTML
added Reflect.compare
fixed "".split() in Neko (now returns [""] instead of [])
bugfix for swf-lib f9 classes ordering
added EReg.customReplace
added neko.Lib.lazyLoad and improved neko.net.Poll for Neko 1.6.1
prevented static fields in interfaces
added neko.Sys.cpuTime()
fix for protected as3 classes
added support for flash9 XML (in flash.xml package)
added neko.vm.Tls for Neko 1.6.1
added --no-inline
renamed neko.zip.File to neko.zip.Reader
added neko.zip.Writer and neko.zip.CRC32
fixed multilevel Transform.block_vars
added js.SWFObject
fixes for if/switch with null or Null on Flash9
2008-01-13: 1.17
fixed Int32.compare, added Int32.read and Int32.write
fixed type of unitialized registers in flash9
fixed Sqlite transactions (commit and rollback now restart a transaction)
several flash9 optimizations
flash9 debug support (with -D fdb)
set align to TopLeft if not defined for flash9
added neko.vm.Gc
fixed Null should not be a value
bugfix in serialization format with USE_ENUM_INDEXES
added apis in DateTools for time manipulation
bugfix in flash9 : strictly typed local vars used in local functions
always force swf version and sandbox redefinition
added as3hl layer
merge as3 classes
use flash9 fast switch for enums
always use match for enums (no switch even if constant)
fixed DateTools.format %I and %l in Flash/JS
securized Hash for JS and Flash
compiletime F9 class generation for F8 swflib
optimized for loops (Array and IntIter)
added #line support
more f9 Null support for "if" and array declarations
more neko.Web.setCookie parameters
added "inline" for methods and static vars
fixed % type in flash9
2007-10-31: 1.16
use _sans font for default flash traces (better Linux support)
fixed haxe.remoting.Connection compilation for Flash<8
added fix to prevent 64K identifiers limit on Flash<9
ensure order of anonymous fields initialization
fixed haxe.remoting.Connection.urlConnect in JS
use amortized O(1) for Neko Array implementation
ndlls libraries should now use .neko() instead of __a
allowed 'u' utf8 for regexp (needs Neko 1.6.1 regexp.ndll on windows)
onclick and onsubmit JS events returns Bool
fixed inherited constructor of extern class was always private
fixed Ereg.split without 'g' flag on JS/Flash9
fixed haxe.Stack in JS without -debug
added support for -D no-swf-compress
fixed ByteArray.readObject
fixed implements Dynamic in Flash9
removed neko.io.FileInput.eof, fixed neko.io.Input.readLine
fixed haxe.Template for Flash9
added neko.Sys.command optional array of arguments
removed haxe.Proxy
added flash.XMLRequest
fixed Type.enumParameters for Neko
guaranteed order of Type.getEnumConstructs same as code
used index-based dispatch for enums
added Type.enumIndex
fixed enum.toString for Flash and JS
support for -Dnetwork-sandbox
trim -cp and -resource
various genas3 fixes
2007-08-29: 1.15
fixed bug with Enum.construct when Enum have type parameters
change with "untyped" : arguments types are checked (because of opt select)
haxedoc : fixed type parameters display
fix for JS and Flash9 XML parser : allow newlines in attributes
disable Flash9 resources with AS3Gen
error on extra anonymous fields
error on too much big neko array declaration (neko 1.6 max_stack limit)
fixed Flash9 statics slots (FP 9,0,60 compatibility)
fixed Flash9 Type.getClassName
optional enums arguments on Flash9 are now automatically Null
forbid usage of type parameters in static functions
fixed Std.int with negative numbers
fixed some F9 issues with Haxe-specific Array, Date and Math methods
used AS3 namespace for F9 Array and String instance methods
fixed F9 with uninitialized integer registers
fixed F9 + operator with Dynamic/Null operands
added Enum subtyping
fix with remoting threadserver and exceptions
fixed Flash9 dynamic runtime type field access
fixed very tricky typing bug with constructors inheritance
fixed some documentation related parser bug
fixed stack overflow with static setter
fixed package completion bug when -cp points to an not existing dir
fix duplicate sandboxes tags with -swf
__resolve in Haxe Remoting is now public
2007-07-25: 1.14
fixed no error when invalid "catch" expression
remove variance
fixed prototype bug in neko when "Main" class is defined
fixed flash9 xml iterator methods
bugfix in flash9 ByteArray serialization
fixed genAS3 conflicting classes and interfaces
preserve neko output file extension
added flash.Event for Flash9
added --no-output
fixed neko.net.Socket peer and host methods
added neko.io.Process and neko.vm.Ui
added haxe.xml.Proxy
some flash6 fixes
allowed simplequotes for xml attributes in Flash9 and JS
flash9 optimizing compiler
new faster neko binary AST
added haxe.remoting.NekoSocketConnection and SocketProtocol
don't allow for...in iteration with Dynamic or Unknown
added flash9 resources
fixed precedence of ternary operator ?:
2007-05-18: 1.13
fixed bug with local variable masking package in catch type
fixed "Not_found" when enum params differs
added "override" for AS3 generator
fixed stack overflow in typedefs
added haxe.Timer.queue, removed delayedArg (use callback instead)
fixed haxe.remoting.SocketConnection (msg invertions might occur)
add uniqueness check for switch constants
js : HtmlCollection and MetaDom.childNodes are not true Arrays
allowed semicolon after typedef declaration
fixed in-loop closure usage of "for" variable for Flash and JS
added neko.net.ThreadRemotingServer.onXml (to handle crossdomain xml)
more accurate stack trace for socket remoting
prevent some memory leak in haxe.Timer / JS
added flash fullscreen support
added cond?a:b syntax support
added utf8 buffer api
added haxelib "dev" mode
renamed Http.asyncRequest to customRequest
add classes to Neko module export table
fixed parametrized enums for Flash6
fixed bug with completion and interfaces
fixed --flash-use-stage in Flash9
2007-03-06: 1.12
added flash lite support with -D flash_lite
bugfix for Unknown should Unknown
prevent some exceptions in neko.net.ProxyDetect
fixed ByteArray serialization
added neko.Int32
added -x for fast neko scripting
prevent locals from breaking class access (works with imports)
fix in function overriding subtyping
added haxe.remoting.FlashJsConnection
fixed tar support in neko.zip.File
ide completion support using --display
give access to neko.net.Host ip (as Int32)
fixed bug when calling super.UpperCaseMethod()
hide additional flash Array methods
allow leading comma in anonymous types
added haxe.Public interface
added AS3 code generator
field lookup gives priority to superclass over interfaces
improved haxedoc output
fixed bug in neko regexp split/replace when empty match at eol
fixed bug in flash 6-7-8 resources generation
2007-01-28: 1.11
changed StringBuf.add implementation
added haxe.Firebug
allowed variable return type for overriden/implemented methods
display error position in front of each error line
improved error messages when optional arguments not matched
added neko.io.Path
added neko.net.ProxyDetect
bugfix in unify : prevent recursive anonymous objects
haxe.Http call "prepare" only if size is known
added multiple expressions in "case"
serialization : deprecated old string format, use urlEncode/Decode
added flash9 bytearray serialization (to binary string, for neko com)
fixed Type.typeof on some flash9 instances
no more dontUseCache (haxe.Serializer.USE_CACHE, default to false)
small genxml/haxedoc improvements
added Type.enumEq
local function parameters are now inferred in several cases
optional RTTI for Spod Object
bugfix related to callback in neko code generator
more type error stack (now includes type parameters)
type system fixes in anonymous subtyping
added Iterable, changed Lambda
added TAR and GZIP support to neko.io.Zip
compute minimal array content type
fixes in enum switchs
2007-01-01: 1.10
fix in haxe.remoting.SocketConnection.readAnswer
fix in postfix incr/decr and getter/setter
added haxe.Http.fileTransfert for Neko
fixed haxelib to 1.02 (use multipart file transfert)
fixed Array.reverse
added flash.Lib.getURL and fscommand for Flash9
fixed some ignored parse errors
fixed minor syntax : immediate object access
allow extend/implements a typedef
fixed Flash9 AMF remoting
fixed Flash9 bugs in Date object
fixed dynamic Array typing bug
allowed typedef private field access
added Class base class type
AsyncConnection.call callback is now optional
fixed if/switch with no else/default compilation
moved Reflect.createInstance to Type
added Reflect.makeVarArgs
haXelib 1.03 : several developers per project + web interface
2006-11-22: 1.09
added neko.vm.Module and neko.vm.Loader
haxelib : allowed spaces in "run" arguments
allowed Thread comparison
fixed bug in SWF6 compilation
allowed either Mysql or Mysql5 usage
replaced db.Connection.hasFeature by db.Connection.dbName
added Socket.custom field
moved neko.Thread to neko.vm.Thread
define haxe_109 (for api changes)
fixes in haxe.remoting.Connection and haxe.Unserializer for F9
added haxe.remoting.Connection.urlConnect for JS
allowed private typedef fields
added neko.net.ThreadServer, ThreadRemotingServer and Poll
removed neko.net.RemotingBuffer
relaxed enums switchs (allow value in first case)
changed "cast" codegeneration (fix some F9 usages)
change in POST data handling in mod_neko (max 256K, except multipart)
added neko.Web.getClientHeaders and neko.Web.flush
"callback" is now a keyword
fixed stack overflow when typedef = Dynamic
fixed Reflect.createInstance on F9
Array : slice optional length, fixed neko slice & splice
+ fixed cast return type
2006-10-29: 1.08
fixed bug in flash -debug
fixed Sqlite result .length
fixed missing "." in OSX/Linux default classpath
fixed haxelib NDLL autoloading on OSX
fixed bug in deserialization of "\\\r" sequence
added inheritance and fields getter/setter to xml output
haxedoc 2.0
fixed neko native enum serialization
fixed "all constructors matched" for enums without params
fixed returned value semantics in neko (prevent remoting leak)
more documentation
added haxe.rtti package (classes can implement haxe.rtti.Infos)
fixed windows line endings in exclude files under linux/osx
fixed small bug in "cast" syntax
added "callback" for partial function application
added --auto-xml for future haxeFD usage
fixed Reflect.isFunction
minor bugfix in JS code generator
new neko.net package
allow recursive remoting proxys (skip instead of error)
added neko.Thread and neko.Lock MultiThread classes
added neko.net.ServerLoop for multiple clients handling
2006-09-11: 1.07
fixed resources in Neko
typedef, override, package and f9dynamic are now keywords
slighly changed error format output
fixed "undefined" serialization and Type.typeof
some fixes in haxelib
set default classpath for non windows systems
added variance
fixed bug in bounded type parameters
fixed scope bug in try/catch with Flash9
added remoting over XMLSocket and LocalConnection for Flash9
fixed Std.is(*,null) = false
allowed >64K Haxe/neko strings
-debug and stack traces support for Flash and JS
minor changes in xml output
2006-08-28: 1.06
allowed extern enums
use only matching construct when parameters are matched
fixed bug preventing & char to be sent between JS and Flash remoting
improved flash9 api (more strict)
flash9 xml : use JS ReXml parser
added neko.io package (Input/Output)
moved neko.File and neko.Socket to neko.io package
fixed flash optional arguments (when extending flash.MC)
fixed neko native serialization problems
variable modification does not have side effects in 'for x in a...b'
jit disabled by default for neko web server
enable flash7-8 libraries usage from flash9
unknown identifier become "class not found" when representing a classpath
changed haxe.PosInfos handling
added -debug (removed --flash-debug) effective on flash9 and neko only now
added Type.typeof
improved Serializer speed
added Serialization support for Date, Hash, IntHash, List
added flash9 and JS IE/Opera class reflection
added haxe.xml.Check and haxe.xml.Fast
added Xml.parent
added haxelib
added ArrayAccess interface
2006-08-16: 1.05
moved Md5 to haxe package.
some method renamed in neko.FileSystem.
added neko.remoting.Server.setLogger
fixed bug in haxe.Serializer on neko (was preventing List serialization)
fixed bugs in Haxe.Unserializer on neko (invalid enum tag & pbs with UTF8 strings)
fixed sqlite escape & quote , added BOOL support
allowed direct property access in getter/setter (prevent rec loop)
allowed event-driven neko http requests
forbidden "name" static in js
don't allow variable redeclaration in subclasses
added && || and ! in conditional compilation rules
metas : removed __construct__ and class.toString.
metas : __super__ and __interfaces__ now optional
added Type api (seperated from Reflect)
flash 9 support
2006-07-25: 1.04
added macros in haxe.Template
allowed static variables access from a signature shortcut
allowed new Signature when signature is a class
fixed : modulo priority is now higher than mult and div
fixed bug in haxe.Proxy generation
fixed more stack overflows with recursive signatures
fixed bug in class <: anonymous subtyping (inherited fields)
override is not mandatory by default (need --override)
added neko just-in-time
fixed bugs in haxe.Serializer and haxe.Unserializer (enum format change)
changed "signature" by "typedef" (more comprehensible)
restricted objects comparisons
fixed bug with js operator priority
improved performances for haxe.Serializer and haxe.Unserializer
fixed bug in static variable lookup (should look class in the last case)
prevented several prints of "not enough arguments".
2006-06-23: 1.03
haxedoc executable now part of the distribution
removed selectDB from the neko.db.Connection API
added optional parameters with selection
removed --no-flash-opt-args
changes in SWF packages handling
fixed optional leading comma in anonymous object and array values
fixed bug in inheritend constructor type parameters
fixed bug in type_field with inherited type parameters
added haxe.Proxy
added code transformations for swf/js block variables
fixed very tricky bug with constraint parameters used together with polymorphic methods
added selective import (import x.y.Class.InnerType)
added optional enum constructor parameters
added opened anonymous types (no more Unknown has no field...)
fixed "MovieClip extends flash.MovieClip".
added Reflect.copy
added neko.Random
added Date.fromString
fixed bug in haxe.Unserializer, slighlty optimized haxe.Serializer
added __setfield magic (complete __resolve)
added explicit override when overriding methods
2006-06-08: 1.02
fixed stack overflow when recursive class <: recursive signature
improved a bit commandline : allow several hxml arguments
added {> Class, fields... } types declarations
added cast without type (less dangerous than untyped)
no stage objects by default, added --flash-use-stage
added haxe.remoting.DelayedConnection
added -exclude
removed classpath from neko debug infos filenames
fixed bug in Neko empty Array.pop and Neko EReg.replace ""
fixed nodeValue for Neko XML comments, doctype, prolog
improved DocView : formating, signatures, files generation
added neko.zip package
fixed bug in neko.File binary flags
fixed problems when downloading large files using haxe.Http under Neko
neko.db.Connection and neko.db.ResultSet are now interfaces
added neko.db.Sqlite and neko sqlite ndll
mod_neko2.ndll for Apache2 in Windows distribution
fixed bug in static properties method resolution
change js.Dom : use cascading signatures and improved api
added haxe.unit Unit test framework
2006-05-25: 1.01
added neko.Utf8
Serializer/Unserializer now support utf8 strings
allowed subtyping of prop accesses public/private when implementing an interface
removed "eval" from Remoting APIs (only calls - more easy to handle).
added flash6 support
fixed Std.is on different platforms (interfaces implements interface)
added AsyncConnection.amfConnect for flash
added SWF overflow checks
changed "property" to "var"
don't allow monorph unification with Dynamic (more safe)
allowed multiple parsing and typing errors
review and completed commandline options
error on backwards constant integer iterators
remoting proxy constructor is now public
fixed -swf-header override the swflib background color
moved all remoting classes into the haxe.remoting package
added haxe.remoting.LocalConnection
2006-05-17: 1.0
fixed small bugs in JS Xml Parser (empty attribute, newlines in attributes)
added default Content-Type for haxe.Http in JS
haxe.AsyncConnection : onError should not be call if error occur in onData
fixed infinite loop if haxe.Unserializer.readDigits reach eof on JS/Flash
fixed bugs in neko.Web and neko.Sys (some methods returning "null" instead of null)
added neko.Socket.setBlocking for nonblocking sockets
fixed bug in js generator when using cascading iterators
fixed typing bug when overloading parametrized method
fixed bug in js generator when "try" without curly braces.
allowed enum catching
added remoting proxys
allowed neko.Web API commandline emulation outside mod_neko
removed subtyping Anon :> Instance
added signatures, Iterator is now a signature
getter/setter and public/private unification
allowed anonymous declaration with interface-style syntax (for signatures)
optimized code generated for underscore in enum matches parameters
fixed flash/js String.charCodeAt(outside) => null
fixed neko charAt(outside) => ""
added errors for strings containing \0 in JS and Flash
added HAXE_LIBRARY_PATH environment variable support
fixed interfaces inheritance : can't extend, can implement (type-sums)
fixed fixed >64K resource bug in SWF
fixed newline problems with Flash/JS Connection
2006-05-02: RC1
added the Socket class
fixed a bug of returned value in neko with 6 or more parameters
added "Missing type" error for catchs.
added regular expressions (still missing Flash implementation)
fixed type printing and parenthesis in type declarations
different behavior when elements removed during Array.iteration
fixed genswf : local variables used in for...function
improved type parameters structure coherency
enable usage of Spod without Transaction
implemented neko.db.Transaction.isDeadlock
slighly relaxed one of the javascript generator constraint
added haxe.Template
moved Log , PosInfos and ImportAll to haxe package
completed private class/interface/enum support
removed Array.indexes
added __resolve compile-time support when class implement Dynamic
added haxe Remoting
added "module with different case" error (for windows)
added Reflect.resolveClass, Reflect.resolveEnum, Reflect.setPrototype
added access to classes by name in genneko
added enum.__ename__
fixed Std.is(e,enum)
fixed infinite loop in neko EReg split/replace and epsilon matching
added neko native serialization support
fixed syntax for multiple constraints in type parameter
added recursive type parameters contraints (T : C constraints)
updated Xml handling
2006-04-17: beta 5
fixed bug : continue in do...while
changed typing order for do...while (infer condition after block)
fixed JS "catch" generation
fixed extending flash.* extern class
fixed bug in neko generator w/ closures
fixed bug in js generator (return switch need correct "this" context)
fixed bug in for x in a...b : invalid local variables overridding
added properties
fixed bug in js generator : while...switch...break
new List implementation
can use static function __init__ on every platform
bug fixes in Reflect.fields
added Hash.remove, changed Hash/JS implementation
added flash __delete__ support
added neko.db.Object, Manager, Transaction
fixed neko class.__interfaces__
added "assigning a value to itself" error
added automatic PosInfos when is last parameter
added polymorphic methods
added check_flash_args support
2006-04-02: beta 4
fixed javascript events case
fixed invalid use of physeq
fixed + type inference
added -altfmt
allowed anonymous <: class subtyping
relaxed unifications of expressions in "for" and "while"
more methods in List
syntax changes : mandatory parenthesis for "for" and "while"
allowed any kind of identifier almost everywhere
moved tools, flash, js and neko inside "std"
no need for 0x in flash header bgcolor
added -res
fixed type parameter contraint holes
Std.is Dynamic always returns true
added Enum.toString
neko : env locals can be modified in inner functions
completed js keywords list in generator
added Reflect.typeof
prioritize neko.Lib.load static calls
fixed bugs in for...in optimization with continue
fixed Reflect fields, added documentation, added Class
added javascript closures, fixed null closures on flash and Neko
added javascript __init__ statics and js.XMLHttpRequest
added neko.Stack
fixed bug in Std.ord
convert neko string to haxe string on catch
automaticaly creates empty clips for classes extending flash.MovieClip
unify stack : several meaningful unification errors
added cast operation and keyword
2006-03-11: beta 3
javascript generator
optimized for in interval
renaming of locals (name must be unique)
added uncaught exceptions handling in Flash
fixed Bool.true == true and Bool.false == false on all platforms
fixed matching on Bool different from enums
removed -fplayer (use -D instead) and added -fheader
fixed infinity is Int
added "here" special identifier
neko Apis : File, FileSystem, Sys
added base JS API
2006-02-19: beta 2
renamed neko.db.Result to neko.db.ResultSet
added Date support for Mysql results
added private fields for static class anonymous types
disambigous >=, >>= and >>>=
fixed inheritance bug in swf and neko generators
improved function parameters type error reporting.
allowed variable number of args for flash.* constructors.
added Math.random(), Reflect.empty()
added flash.XMLSocket and flash.Timer classes
completed Std class with conversion functions and others.
completed flash.Lib class with flash toplevel functions.
fixed bugs in neko webserver
2006-02-04: beta 1
allowed array literals to be dynamic
use neko 1.2 commandline and prototypes
changed #cond to #if cond for conditional compilation
all fields are defined to null by default
defined __class__ and other meta accesses for Flash and Neko
fixed type hole for compiler-know types (should not resolve using imports)
changed packages : neko.* and flash.* (with protection)
added Lazy types : type the fields when they are needed with recursion
untyped accesses are monomorphs, not dynamics
generated __string check that toString() return an object
XmlParser and other APIs for Neko
fixed escaped chars in Neko generation
conservative static initialization order
allowed no type parameters for new Class
function types carry parameter names
anonymous types contain private variables (for private static accesses)
added optional name for anonymous types in typer (for static accesses)
private classes and enums (partial support)
improved error message for invalid number of arguments
flash extern classes can take variable number of args.
added -swf-lib for importing SWF library
added neko.db package
2005-12-23: alpha 5
added -main commandline parameter
catches are now working with Neko
restricted catch types for type-safety
added constructor inheritance + check if superconstructor is called
allowed Dynamic-only subtyping on type parameters
added method closures to Neko generation
added class Reflect
added License : libraries are BSD
added -xml documentation output
allowed class instance :> anonymous subtyping
2005-12-10: alpha 4
forbid break and continue outside loops
fixed SWF generation bugs
added SWF "extends" support
added method closures
added some flash lowlevel operations (__xxx__)
added Log, LogInfos and trace
added Neko generation
fixed problems with conditional compilation macros
2005-11-30: alpha 3
added Flash extern classes
Boot initialization
added "untyped"
added conditional compilation
added interfaces
changed iterators from closures to objects
added (XML)Node and XmlParser for Flash
2005-11-25: alpha 2
swf generation (missing iterators)
some typing fixes
2005-11-17: alpha 1b
fix some bugs
changed package tests.lang
2005-11-14: alpha 1
lexer
parser
typer
haxe_3.2.1+dfsg.orig/extra/CONTRIB.txt 0000664 0001750 0001750 00000005133 12607337712 017312 0 ustar andy andy 0000000 0000000 Contributor License Agreement :
You accept and agree to the following terms and conditions for Your present and future Contributions submitted to the project Haxe :
1) Definitions
"Contribution" : any source code, documentation, including any modifications or additions to an existing work that is intentionally submitted by You to the Haxe Foundation for inclusion in, or documentation of, any of the products managed and maintained by the Haxe Foundation.
"Submitted" means any form or electronic, verbal or written communication, including but not limited to communication on electronic mailing lists, source code control systems and issue tracking system that are managed by, or on behalf of, the Haxe Foundation for the purpose of improving Haxe.
2) Grant of Copyright License. Subject to the terms and conditions of this Grant, You hereby grant to the Haxe Foundation and to recipients of software distributed by the Haxe Foundation a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare derivative works of, publicly display, publicly perform, sublicense, and distribute Your Contributions and such derivative works.
3) You represent that you are legally entitled to grant the above license. If your employer(s) has rights to intellectual property that you create that includes your Contributions, you represent that you have received permission to make Contributions on behalf of that employer, that your employer has waived such rights for your Contributions to the Haxe Foundation, or that your employer has executed a separate Corporate Contributor License Grant with the Haxe Foundation.
4) You represent that each of Your Contributions is Your original creation (see section 7 for submissions on behalf of others). You represent that Your Contribution submissions include complete details of any third-party license or other restriction (including, but not limited to, related patents and trademarks) of which you are personally aware and which are associated with any part of Your Contributions.
5) You are not expected to provide support for Your Contributions, except to the extent You desire to provide support. You may provide support for free, for a fee, or not at all. Unless required by applicable law or agreed to in writing, You provide Your Contributions on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON- INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE.
Full Name :
Email :
Mailing Address :
Country :
Signature: haxe_3.2.1+dfsg.orig/extra/EnvVarUpdate.nsh 0000664 0001750 0001750 00000024101 12607337712 020523 0 ustar andy andy 0000000 0000000 /**
* EnvVarUpdate.nsh
* : Environmental Variables: append, prepend, and remove entries
*
* WARNING: If you use StrFunc.nsh header then include it before this file
* with all required definitions. This is to avoid conflicts
*
* Usage:
* ${EnvVarUpdate} "ResultVar" "EnvVarName" "Action" "RegLoc" "PathString"
*
* Credits:
* Version 1.0
* * Cal Turney (turnec2)
* * Amir Szekely (KiCHiK) and e-circ for developing the forerunners of this
* function: AddToPath, un.RemoveFromPath, AddToEnvVar, un.RemoveFromEnvVar,
* WriteEnvStr, and un.DeleteEnvStr
* * Diego Pedroso (deguix) for StrTok
* * Kevin English (kenglish_hi) for StrContains
* * Hendri Adriaens (Smile2Me), Diego Pedroso (deguix), and Dan Fuhry
* (dandaman32) for StrReplace
*
* Version 1.1 (compatibility with StrFunc.nsh)
* * techtonik
*
* http://nsis.sourceforge.net/Environmental_Variables:_append%2C_prepend%2C_and_remove_entries
*
*/
!ifndef ENVVARUPDATE_FUNCTION
!define ENVVARUPDATE_FUNCTION
!verbose push
!verbose 3
!include "LogicLib.nsh"
!include "WinMessages.NSH"
!include "StrFunc.nsh"
; ---- Fix for conflict if StrFunc.nsh is already includes in main file -----------------------
!macro _IncludeStrFunction StrFuncName
!ifndef ${StrFuncName}_INCLUDED
${${StrFuncName}}
!endif
!ifndef Un${StrFuncName}_INCLUDED
${Un${StrFuncName}}
!endif
!define un.${StrFuncName} "${Un${StrFuncName}}"
!macroend
!insertmacro _IncludeStrFunction StrTok
!insertmacro _IncludeStrFunction StrStr
!insertmacro _IncludeStrFunction StrRep
; ---------------------------------- Macro Definitions ----------------------------------------
!macro _EnvVarUpdateConstructor ResultVar EnvVarName Action Regloc PathString
Push "${EnvVarName}"
Push "${Action}"
Push "${RegLoc}"
Push "${PathString}"
Call EnvVarUpdate
Pop "${ResultVar}"
!macroend
!define EnvVarUpdate '!insertmacro "_EnvVarUpdateConstructor"'
!macro _unEnvVarUpdateConstructor ResultVar EnvVarName Action Regloc PathString
Push "${EnvVarName}"
Push "${Action}"
Push "${RegLoc}"
Push "${PathString}"
Call un.EnvVarUpdate
Pop "${ResultVar}"
!macroend
!define un.EnvVarUpdate '!insertmacro "_unEnvVarUpdateConstructor"'
; ---------------------------------- Macro Definitions end-------------------------------------
;----------------------------------- EnvVarUpdate start----------------------------------------
!define hklm_all_users 'HKLM "SYSTEM\CurrentControlSet\Control\Session Manager\Environment"'
!define hkcu_current_user 'HKCU "Environment"'
!macro EnvVarUpdate UN
Function ${UN}EnvVarUpdate
Push $0
Exch 4
Exch $1
Exch 3
Exch $2
Exch 2
Exch $3
Exch
Exch $4
Push $5
Push $6
Push $7
Push $8
Push $9
Push $R0
/* After this point:
-------------------------
$0 = ResultVar (returned)
$1 = EnvVarName (input)
$2 = Action (input)
$3 = RegLoc (input)
$4 = PathString (input)
$5 = Orig EnvVar (read from registry)
$6 = Len of $0 (temp)
$7 = tempstr1 (temp)
$8 = Entry counter (temp)
$9 = tempstr2 (temp)
$R0 = tempChar (temp) */
; Step 1: Read contents of EnvVarName from RegLoc
;
; Check for empty EnvVarName
${If} $1 == ""
SetErrors
DetailPrint "ERROR: EnvVarName is blank"
Goto EnvVarUpdate_Restore_Vars
${EndIf}
; Check for valid Action
${If} $2 != "A"
${AndIf} $2 != "P"
${AndIf} $2 != "R"
SetErrors
DetailPrint "ERROR: Invalid Action - must be A, P, or R"
Goto EnvVarUpdate_Restore_Vars
${EndIf}
${If} $3 == HKLM
ReadRegStr $5 ${hklm_all_users} $1 ; Get EnvVarName from all users into $5
${ElseIf} $3 == HKCU
ReadRegStr $5 ${hkcu_current_user} $1 ; Read EnvVarName from current user into $5
${Else}
SetErrors
DetailPrint 'ERROR: Action is [$3] but must be "HKLM" or HKCU"'
Goto EnvVarUpdate_Restore_Vars
${EndIf}
; Check for empty PathString
${If} $4 == ""
SetErrors
DetailPrint "ERROR: PathString is blank"
Goto EnvVarUpdate_Restore_Vars
${EndIf}
; Make sure we've got some work to do
${If} $5 == ""
${AndIf} $2 == "R"
SetErrors
DetailPrint "$1 is empty - Nothing to remove"
Goto EnvVarUpdate_Restore_Vars
${EndIf}
; Step 2: Scrub EnvVar
;
StrCpy $0 $5 ; Copy the contents to $0
; Remove spaces around semicolons (NOTE: spaces before the 1st entry or
; after the last one are not removed here but instead in Step 3)
${If} $0 != "" ; If EnvVar is not empty ...
${Do}
${${UN}StrStr} $7 $0 " ;"
${If} $7 == ""
${ExitDo}
${EndIf}
${${UN}StrRep} $0 $0 " ;" ";" ; Remove ';'
${Loop}
${Do}
${${UN}StrStr} $7 $0 "; "
${If} $7 == ""
${ExitDo}
${EndIf}
${${UN}StrRep} $0 $0 "; " ";" ; Remove ';'
${Loop}
${Do}
${${UN}StrStr} $7 $0 ";;"
${If} $7 == ""
${ExitDo}
${EndIf}
${${UN}StrRep} $0 $0 ";;" ";"
${Loop}
; Remove a leading or trailing semicolon from EnvVar
StrCpy $7 $0 1 0
${If} $7 == ";"
StrCpy $0 $0 "" 1 ; Change ';' to ''
${EndIf}
StrLen $6 $0
IntOp $6 $6 - 1
StrCpy $7 $0 1 $6
${If} $7 == ";"
StrCpy $0 $0 $6 ; Change ';' to ''
${EndIf}
; DetailPrint "Scrubbed $1: [$0]" ; Uncomment to debug
${EndIf}
/* Step 3. Remove all instances of the target path/string (even if "A" or "P")
$6 = bool flag (1 = found and removed PathString)
$7 = a string (e.g. path) delimited by semicolon(s)
$8 = entry counter starting at 0
$9 = copy of $0
$R0 = tempChar */
${If} $5 != "" ; If EnvVar is not empty ...
StrCpy $9 $0
StrCpy $0 ""
StrCpy $8 0
StrCpy $6 0
${Do}
${${UN}StrTok} $7 $9 ";" $8 "0" ; $7 = next entry, $8 = entry counter
${If} $7 == "" ; If we've run out of entries,
${ExitDo} ; were done
${EndIf} ;
; Remove leading and trailing spaces from this entry (critical step for Action=Remove)
${Do}
StrCpy $R0 $7 1
${If} $R0 != " "
${ExitDo}
${EndIf}
StrCpy $7 $7 "" 1 ; Remove leading space
${Loop}
${Do}
StrCpy $R0 $7 1 -1
${If} $R0 != " "
${ExitDo}
${EndIf}
StrCpy $7 $7 -1 ; Remove trailing space
${Loop}
${If} $7 == $4 ; If string matches, remove it by not appending it
StrCpy $6 1 ; Set 'found' flag
${ElseIf} $7 != $4 ; If string does NOT match
${AndIf} $0 == "" ; and the 1st string being added to $0,
StrCpy $0 $7 ; copy it to $0 without a prepended semicolon
${ElseIf} $7 != $4 ; If string does NOT match
${AndIf} $0 != "" ; and this is NOT the 1st string to be added to $0,
StrCpy $0 $0;$7 ; append path to $0 with a prepended semicolon
${EndIf} ;
IntOp $8 $8 + 1 ; Bump counter
${Loop} ; Check for duplicates until we run out of paths
${EndIf}
; Step 4: Perform the requested Action
;
${If} $2 != "R" ; If Append or Prepend
${If} $6 == 1 ; And if we found the target
DetailPrint "Target is already present in $1. It will be removed and"
${EndIf}
${If} $0 == "" ; If EnvVar is (now) empty
StrCpy $0 $4 ; just copy PathString to EnvVar
${If} $6 == 0 ; If found flag is either 0
${OrIf} $6 == "" ; or blank (if EnvVarName is empty)
DetailPrint "$1 was empty and has been updated with the target"
${EndIf}
${ElseIf} $2 == "A" ; If Append (and EnvVar is not empty),
StrCpy $0 $0;$4 ; append PathString
${If} $6 == 1
DetailPrint "appended to $1"
${Else}
DetailPrint "Target was appended to $1"
${EndIf}
${Else} ; If Prepend (and EnvVar is not empty),
StrCpy $0 $4;$0 ; prepend PathString
${If} $6 == 1
DetailPrint "prepended to $1"
${Else}
DetailPrint "Target was prepended to $1"
${EndIf}
${EndIf}
${Else} ; If Action = Remove
${If} $6 == 1 ; and we found the target
DetailPrint "Target was found and removed from $1"
${Else}
DetailPrint "Target was NOT found in $1 (nothing to remove)"
${EndIf}
${If} $0 == ""
DetailPrint "$1 is now empty"
${EndIf}
${EndIf}
; Step 5: Update the registry at RegLoc with the updated EnvVar and announce the change
;
ClearErrors
${If} $3 == HKLM
WriteRegExpandStr ${hklm_all_users} $1 $0 ; Write it in all users section
${ElseIf} $3 == HKCU
WriteRegExpandStr ${hkcu_current_user} $1 $0 ; Write it to current user section
${EndIf}
IfErrors 0 +4
MessageBox MB_OK|MB_ICONEXCLAMATION "Could not write updated $1 to $3"
DetailPrint "Could not write updated $1 to $3"
Goto EnvVarUpdate_Restore_Vars
; "Export" our change
SendMessage ${HWND_BROADCAST} ${WM_WININICHANGE} 0 "STR:Environment" /TIMEOUT=5000
EnvVarUpdate_Restore_Vars:
;
; Restore the user's variables and return ResultVar
Pop $R0
Pop $9
Pop $8
Pop $7
Pop $6
Pop $5
Pop $4
Pop $3
Pop $2
Pop $1
Push $0 ; Push my $0 (ResultVar)
Exch
Pop $0 ; Restore his $0
FunctionEnd
!macroend ; EnvVarUpdate UN
!insertmacro EnvVarUpdate ""
!insertmacro EnvVarUpdate "un."
;----------------------------------- EnvVarUpdate end----------------------------------------
!verbose pop
!endif
haxe_3.2.1+dfsg.orig/extra/ImportAll.hx 0000664 0001750 0001750 00000007334 12607337712 017722 0 ustar andy andy 0000000 0000000 /*
* Copyright (c) 2005, The Haxe Project Contributors
* All rights reserved.
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE HAXE PROJECT CONTRIBUTORS "AS IS" AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE HAXE PROJECT CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
* DAMAGE.
*/
import haxe.macro.Context;
class ImportAll {
public static function run( ?pack ) {
if( pack == null ) {
pack = "";
haxe.macro.Compiler.define("doc_gen");
}
switch( pack ) {
case "php":
if( !Context.defined("php") ) return;
case "neko":
if( !Context.defined("neko") ) return;
case "js":
if( !Context.defined("js") ) return;
case "cpp":
if( !Context.defined("cpp") ) return;
case "flash":
if( !Context.defined("flash9") ) return;
case "sys":
if( !Context.defined("neko") && !Context.defined("php") && !Context.defined("cpp") ) return;
case "java":
if( !Context.defined("java") ) return;
case "cs":
if( !Context.defined("cs") ) return;
case "python":
if( !Context.defined("python") ) return;
case "tools":
return;
case "build-tool":
return;
}
for( p in Context.getClassPath() ) {
if( 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" )
continue;
var full = (pack == "") ? file : pack + "." + file;
if( StringTools.endsWith(file, ".hx") ) {
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( !(Context.defined("neko") || Context.defined("php") || Context.defined("cpp")) ) 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("neko") ) 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 "sys.db.Sqlite" | "sys.db.Mysql" | "cs.db.AdoNet": continue;
}
Context.getModule(cl);
} else if( sys.FileSystem.isDirectory(p + "/" + file) )
run(full);
}
}
}
}
haxe_3.2.1+dfsg.orig/extra/LICENSE.txt 0000664 0001750 0001750 00000117637 12607337712 017311 0 ustar andy andy 0000000 0000000 Haxe Licenses
-------------
For details about Haxe Licenses, please read http://haxe.org/doc/license
The MIT Licence :
--------------------------
Copyright (C)2005-2012 Haxe Foundation
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
The Haxe compiler GPL License :
-------------------------------
GNU GENERAL PUBLIC LICENSE
Version 2, June 1991
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
License is intended to guarantee your freedom to share and change free
software--to make sure the software is free for all its users. This
General Public License applies to most of the Free Software
Foundation's software and to any other program whose authors commit to
using it. (Some other Free Software Foundation software is covered by
the GNU Library General Public License instead.) You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
this service if you wish), that you receive source code or can get it
if you want it, that you can change the software or use pieces of it
in new free programs; and that you know you can do these things.
To protect your rights, we need to make restrictions that forbid
anyone to deny you these rights or to ask you to surrender the rights.
These restrictions translate to certain responsibilities for you if you
distribute copies of the software, or if you modify it.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must give the recipients all the rights that
you have. You must make sure that they, too, receive or can get the
source code. And you must show them these terms so they know their
rights.
We protect your rights with two steps: (1) copyright the software, and
(2) offer you this license which gives you legal permission to copy,
distribute and/or modify the software.
Also, for each author's protection and ours, we want to make certain
that everyone understands that there is no warranty for this free
software. If the software is modified by someone else and passed on, we
want its recipients to know that what they have is not the original, so
that any problems introduced by others will not reflect on the original
authors' reputations.
Finally, any free program is threatened constantly by software
patents. We wish to avoid the danger that redistributors of a free
program will individually obtain patent licenses, in effect making the
program proprietary. To prevent this, we have made it clear that any
patent must be licensed for everyone's free use or not licensed at all.
The precise terms and conditions for copying, distribution and
modification follow.
GNU GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License applies to any program or other work which contains
a notice placed by the copyright holder saying it may be distributed
under the terms of this General Public License. The "Program", below,
refers to any such program or work, and a "work based on the Program"
means either the Program or any derivative work under copyright law:
that is to say, a work containing the Program or a portion of it,
either verbatim or with modifications and/or translated into another
language. (Hereinafter, translation is included without limitation in
the term "modification".) Each licensee is addressed as "you".
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running the Program is not restricted, and the output from the Program
is covered only if its contents constitute a work based on the
Program (independent of having been made by running the Program).
Whether that is true depends on what the Program does.
1. You may copy and distribute verbatim copies of the Program's
source code as you receive it, in any medium, provided that you
conspicuously and appropriately publish on each copy an appropriate
copyright notice and disclaimer of warranty; keep intact all the
notices that refer to this License and to the absence of any warranty;
and give any other recipients of the Program a copy of this License
along with the Program.
You may charge a fee for the physical act of transferring a copy, and
you may at your option offer warranty protection in exchange for a fee.
2. You may modify your copy or copies of the Program or any portion
of it, thus forming a work based on the Program, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
a) You must cause the modified files to carry prominent notices
stating that you changed the files and the date of any change.
b) You must cause any work that you distribute or publish, that in
whole or in part contains or is derived from the Program or any
part thereof, to be licensed as a whole at no charge to all third
parties under the terms of this License.
c) If the modified program normally reads commands interactively
when run, you must cause it, when started running for such
interactive use in the most ordinary way, to print or display an
announcement including an appropriate copyright notice and a
notice that there is no warranty (or else, saying that you provide
a warranty) and that users may redistribute the program under
these conditions, and telling the user how to view a copy of this
License. (Exception: if the Program itself is interactive but
does not normally print such an announcement, your work based on
the Program is not required to print an announcement.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Program,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Program, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote it.
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Program.
In addition, mere aggregation of another work not based on the Program
with the Program (or with a work based on the Program) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may copy and distribute the Program (or a work based on it,
under Section 2) in object code or executable form under the terms of
Sections 1 and 2 above provided that you also do one of the following:
a) Accompany it with the complete corresponding machine-readable
source code, which must be distributed under the terms of Sections
1 and 2 above on a medium customarily used for software interchange; or,
b) Accompany it with a written offer, valid for at least three
years, to give any third party, for a charge no more than your
cost of physically performing source distribution, a complete
machine-readable copy of the corresponding source code, to be
distributed under the terms of Sections 1 and 2 above on a medium
customarily used for software interchange; or,
c) Accompany it with the information you received as to the offer
to distribute corresponding source code. (This alternative is
allowed only for noncommercial distribution and only if you
received the program in object code or executable form with such
an offer, in accord with Subsection b above.)
The source code for a work means the preferred form of the work for
making modifications to it. For an executable work, complete source
code means all the source code for all modules it contains, plus any
associated interface definition files, plus the scripts used to
control compilation and installation of the executable. However, as a
special exception, the source code distributed need not include
anything that is normally distributed (in either source or binary
form) with the major components (compiler, kernel, and so on) of the
operating system on which the executable runs, unless that component
itself accompanies the executable.
If distribution of executable or object code is made by offering
access to copy from a designated place, then offering equivalent
access to copy the source code from the same place counts as
distribution of the source code, even though third parties are not
compelled to copy the source along with the object code.
4. You may not copy, modify, sublicense, or distribute the Program
except as expressly provided under this License. Any attempt
otherwise to copy, modify, sublicense or distribute the Program is
void, and will automatically terminate your rights under this License.
However, parties who have received copies, or rights, from you under
this License will not have their licenses terminated so long as such
parties remain in full compliance.
5. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Program or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Program (or any work based on the
Program), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Program or works based on it.
6. Each time you redistribute the Program (or any work based on the
Program), the recipient automatically receives a license from the
original licensor to copy, distribute or modify the Program subject to
these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties to
this License.
7. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Program at all. For example, if a patent
license would not permit royalty-free redistribution of the Program by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Program.
If any portion of this section is held invalid or unenforceable under
any particular circumstance, the balance of the section is intended to
apply and the section as a whole is intended to apply in other
circumstances.
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system, which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
8. If the distribution and/or use of the Program is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Program under this License
may add an explicit geographical distribution limitation excluding
those countries, so that distribution is permitted only in or among
countries not thus excluded. In such case, this License incorporates
the limitation as if written in the body of this License.
9. The Free Software Foundation may publish revised and/or new versions
of the General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the Program
specifies a version number of this License which applies to it and "any
later version", you have the option of following the terms and conditions
either of that version or of any later version published by the Free
Software Foundation. If the Program does not specify a version number of
this License, you may choose any version ever published by the Free Software
Foundation.
10. If you wish to incorporate parts of the Program into other free
programs whose distribution conditions are different, write to the author
to ask for permission. For software which is copyrighted by the Free
Software Foundation, write to the Free Software Foundation; we sometimes
make exceptions for this. Our decision will be guided by the two goals
of preserving the free status of all derivatives of our free software and
of promoting the sharing and reuse of software generally.
NO WARRANTY
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
REPAIR OR CORRECTION.
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGES.
END OF TERMS AND CONDITIONS
The Neko LGPL License :
-----------------------
GNU LESSER GENERAL PUBLIC LICENSE
Version 2.1, February 1999
Copyright (C) 1991, 1999 Free Software Foundation, Inc.
51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
[This is the first released version of the Lesser GPL. It also counts
as the successor of the GNU Library Public License, version 2, hence
the version number 2.1.]
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
Licenses are intended to guarantee your freedom to share and change
free software--to make sure the software is free for all its users.
This license, the Lesser General Public License, applies to some
specially designated software packages--typically libraries--of the
Free Software Foundation and other authors who decide to use it. You
can use it too, but we suggest you first think carefully about whether
this license or the ordinary General Public License is the better
strategy to use in any particular case, based on the explanations below.
When we speak of free software, we are referring to freedom of use,
not price. Our General Public Licenses are designed to make sure that
you have the freedom to distribute copies of free software (and charge
for this service if you wish); that you receive source code or can get
it if you want it; that you can change the software and use pieces of
it in new free programs; and that you are informed that you can do
these things.
To protect your rights, we need to make restrictions that forbid
distributors to deny you these rights or to ask you to surrender these
rights. These restrictions translate to certain responsibilities for
you if you distribute copies of the library or if you modify it.
For example, if you distribute copies of the library, whether gratis
or for a fee, you must give the recipients all the rights that we gave
you. You must make sure that they, too, receive or can get the source
code. If you link other code with the library, you must provide
complete object files to the recipients, so that they can relink them
with the library after making changes to the library and recompiling
it. And you must show them these terms so they know their rights.
We protect your rights with a two-step method: (1) we copyright the
library, and (2) we offer you this license, which gives you legal
permission to copy, distribute and/or modify the library.
To protect each distributor, we want to make it very clear that
there is no warranty for the free library. Also, if the library is
modified by someone else and passed on, the recipients should know
that what they have is not the original version, so that the original
author's reputation will not be affected by problems that might be
introduced by others.
Finally, software patents pose a constant threat to the existence of
any free program. We wish to make sure that a company cannot
effectively restrict the users of a free program by obtaining a
restrictive license from a patent holder. Therefore, we insist that
any patent license obtained for a version of the library must be
consistent with the full freedom of use specified in this license.
Most GNU software, including some libraries, is covered by the
ordinary GNU General Public License. This license, the GNU Lesser
General Public License, applies to certain designated libraries, and
is quite different from the ordinary General Public License. We use
this license for certain libraries in order to permit linking those
libraries into non-free programs.
When a program is linked with a library, whether statically or using
a shared library, the combination of the two is legally speaking a
combined work, a derivative of the original library. The ordinary
General Public License therefore permits such linking only if the
entire combination fits its criteria of freedom. The Lesser General
Public License permits more lax criteria for linking other code with
the library.
We call this license the "Lesser" General Public License because it
does Less to protect the user's freedom than the ordinary General
Public License. It also provides other free software developers Less
of an advantage over competing non-free programs. These disadvantages
are the reason we use the ordinary General Public License for many
libraries. However, the Lesser license provides advantages in certain
special circumstances.
For example, on rare occasions, there may be a special need to
encourage the widest possible use of a certain library, so that it becomes
a de-facto standard. To achieve this, non-free programs must be
allowed to use the library. A more frequent case is that a free
library does the same job as widely used non-free libraries. In this
case, there is little to gain by limiting the free library to free
software only, so we use the Lesser General Public License.
In other cases, permission to use a particular library in non-free
programs enables a greater number of people to use a large body of
free software. For example, permission to use the GNU C Library in
non-free programs enables many more people to use the whole GNU
operating system, as well as its variant, the GNU/Linux operating
system.
Although the Lesser General Public License is Less protective of the
users' freedom, it does ensure that the user of a program that is
linked with the Library has the freedom and the wherewithal to run
that program using a modified version of the Library.
The precise terms and conditions for copying, distribution and
modification follow. Pay close attention to the difference between a
"work based on the library" and a "work that uses the library". The
former contains code derived from the library, whereas the latter must
be combined with the library in order to run.
GNU LESSER GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License Agreement applies to any software library or other
program which contains a notice placed by the copyright holder or
other authorized party saying it may be distributed under the terms of
this Lesser General Public License (also called "this License").
Each licensee is addressed as "you".
A "library" means a collection of software functions and/or data
prepared so as to be conveniently linked with application programs
(which use some of those functions and data) to form executables.
The "Library", below, refers to any such software library or work
which has been distributed under these terms. A "work based on the
Library" means either the Library or any derivative work under
copyright law: that is to say, a work containing the Library or a
portion of it, either verbatim or with modifications and/or translated
straightforwardly into another language. (Hereinafter, translation is
included without limitation in the term "modification".)
"Source code" for a work means the preferred form of the work for
making modifications to it. For a library, complete source code means
all the source code for all modules it contains, plus any associated
interface definition files, plus the scripts used to control compilation
and installation of the library.
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running a program using the Library is not restricted, and output from
such a program is covered only if its contents constitute a work based
on the Library (independent of the use of the Library in a tool for
writing it). Whether that is true depends on what the Library does
and what the program that uses the Library does.
1. You may copy and distribute verbatim copies of the Library's
complete source code as you receive it, in any medium, provided that
you conspicuously and appropriately publish on each copy an
appropriate copyright notice and disclaimer of warranty; keep intact
all the notices that refer to this License and to the absence of any
warranty; and distribute a copy of this License along with the
Library.
You may charge a fee for the physical act of transferring a copy,
and you may at your option offer warranty protection in exchange for a
fee.
2. You may modify your copy or copies of the Library or any portion
of it, thus forming a work based on the Library, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
a) The modified work must itself be a software library.
b) You must cause the files modified to carry prominent notices
stating that you changed the files and the date of any change.
c) You must cause the whole of the work to be licensed at no
charge to all third parties under the terms of this License.
d) If a facility in the modified Library refers to a function or a
table of data to be supplied by an application program that uses
the facility, other than as an argument passed when the facility
is invoked, then you must make a good faith effort to ensure that,
in the event an application does not supply such function or
table, the facility still operates, and performs whatever part of
its purpose remains meaningful.
(For example, a function in a library to compute square roots has
a purpose that is entirely well-defined independent of the
application. Therefore, Subsection 2d requires that any
application-supplied function or table used by this function must
be optional: if the application does not supply it, the square
root function must still compute square roots.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Library,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Library, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote
it.
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Library.
In addition, mere aggregation of another work not based on the Library
with the Library (or with a work based on the Library) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may opt to apply the terms of the ordinary GNU General Public
License instead of this License to a given copy of the Library. To do
this, you must alter all the notices that refer to this License, so
that they refer to the ordinary GNU General Public License, version 2,
instead of to this License. (If a newer version than version 2 of the
ordinary GNU General Public License has appeared, then you can specify
that version instead if you wish.) Do not make any other change in
these notices.
Once this change is made in a given copy, it is irreversible for
that copy, so the ordinary GNU General Public License applies to all
subsequent copies and derivative works made from that copy.
This option is useful when you wish to copy part of the code of
the Library into a program that is not a library.
4. You may copy and distribute the Library (or a portion or
derivative of it, under Section 2) in object code or executable form
under the terms of Sections 1 and 2 above provided that you accompany
it with the complete corresponding machine-readable source code, which
must be distributed under the terms of Sections 1 and 2 above on a
medium customarily used for software interchange.
If distribution of object code is made by offering access to copy
from a designated place, then offering equivalent access to copy the
source code from the same place satisfies the requirement to
distribute the source code, even though third parties are not
compelled to copy the source along with the object code.
5. A program that contains no derivative of any portion of the
Library, but is designed to work with the Library by being compiled or
linked with it, is called a "work that uses the Library". Such a
work, in isolation, is not a derivative work of the Library, and
therefore falls outside the scope of this License.
However, linking a "work that uses the Library" with the Library
creates an executable that is a derivative of the Library (because it
contains portions of the Library), rather than a "work that uses the
library". The executable is therefore covered by this License.
Section 6 states terms for distribution of such executables.
When a "work that uses the Library" uses material from a header file
that is part of the Library, the object code for the work may be a
derivative work of the Library even though the source code is not.
Whether this is true is especially significant if the work can be
linked without the Library, or if the work is itself a library. The
threshold for this to be true is not precisely defined by law.
If such an object file uses only numerical parameters, data
structure layouts and accessors, and small macros and small inline
functions (ten lines or less in length), then the use of the object
file is unrestricted, regardless of whether it is legally a derivative
work. (Executables containing this object code plus portions of the
Library will still fall under Section 6.)
Otherwise, if the work is a derivative of the Library, you may
distribute the object code for the work under the terms of Section 6.
Any executables containing that work also fall under Section 6,
whether or not they are linked directly with the Library itself.
6. As an exception to the Sections above, you may also combine or
link a "work that uses the Library" with the Library to produce a
work containing portions of the Library, and distribute that work
under terms of your choice, provided that the terms permit
modification of the work for the customer's own use and reverse
engineering for debugging such modifications.
You must give prominent notice with each copy of the work that the
Library is used in it and that the Library and its use are covered by
this License. You must supply a copy of this License. If the work
during execution displays copyright notices, you must include the
copyright notice for the Library among them, as well as a reference
directing the user to the copy of this License. Also, you must do one
of these things:
a) Accompany the work with the complete corresponding
machine-readable source code for the Library including whatever
changes were used in the work (which must be distributed under
Sections 1 and 2 above); and, if the work is an executable linked
with the Library, with the complete machine-readable "work that
uses the Library", as object code and/or source code, so that the
user can modify the Library and then relink to produce a modified
executable containing the modified Library. (It is understood
that the user who changes the contents of definitions files in the
Library will not necessarily be able to recompile the application
to use the modified definitions.)
b) Use a suitable shared library mechanism for linking with the
Library. A suitable mechanism is one that (1) uses at run time a
copy of the library already present on the user's computer system,
rather than copying library functions into the executable, and (2)
will operate properly with a modified version of the library, if
the user installs one, as long as the modified version is
interface-compatible with the version that the work was made with.
c) Accompany the work with a written offer, valid for at
least three years, to give the same user the materials
specified in Subsection 6a, above, for a charge no more
than the cost of performing this distribution.
d) If distribution of the work is made by offering access to copy
from a designated place, offer equivalent access to copy the above
specified materials from the same place.
e) Verify that the user has already received a copy of these
materials or that you have already sent this user a copy.
For an executable, the required form of the "work that uses the
Library" must include any data and utility programs needed for
reproducing the executable from it. However, as a special exception,
the materials to be distributed need not include anything that is
normally distributed (in either source or binary form) with the major
components (compiler, kernel, and so on) of the operating system on
which the executable runs, unless that component itself accompanies
the executable.
It may happen that this requirement contradicts the license
restrictions of other proprietary libraries that do not normally
accompany the operating system. Such a contradiction means you cannot
use both them and the Library together in an executable that you
distribute.
7. You may place library facilities that are a work based on the
Library side-by-side in a single library together with other library
facilities not covered by this License, and distribute such a combined
library, provided that the separate distribution of the work based on
the Library and of the other library facilities is otherwise
permitted, and provided that you do these two things:
a) Accompany the combined library with a copy of the same work
based on the Library, uncombined with any other library
facilities. This must be distributed under the terms of the
Sections above.
b) Give prominent notice with the combined library of the fact
that part of it is a work based on the Library, and explaining
where to find the accompanying uncombined form of the same work.
8. You may not copy, modify, sublicense, link with, or distribute
the Library except as expressly provided under this License. Any
attempt otherwise to copy, modify, sublicense, link with, or
distribute the Library is void, and will automatically terminate your
rights under this License. However, parties who have received copies,
or rights, from you under this License will not have their licenses
terminated so long as such parties remain in full compliance.
9. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Library or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Library (or any work based on the
Library), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Library or works based on it.
10. Each time you redistribute the Library (or any work based on the
Library), the recipient automatically receives a license from the
original licensor to copy, distribute, link with or modify the Library
subject to these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties with
this License.
11. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Library at all. For example, if a patent
license would not permit royalty-free redistribution of the Library by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Library.
If any portion of this section is held invalid or unenforceable under any
particular circumstance, the balance of the section is intended to apply,
and the section as a whole is intended to apply in other circumstances.
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
12. If the distribution and/or use of the Library is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Library under this License may add
an explicit geographical distribution limitation excluding those countries,
so that distribution is permitted only in or among countries not thus
excluded. In such case, this License incorporates the limitation as if
written in the body of this License.
13. The Free Software Foundation may publish revised and/or new
versions of the Lesser General Public License from time to time.
Such new versions will be similar in spirit to the present version,
but may differ in detail to address new problems or concerns.
Each version is given a distinguishing version number. If the Library
specifies a version number of this License which applies to it and
"any later version", you have the option of following the terms and
conditions either of that version or of any later version published by
the Free Software Foundation. If the Library does not specify a
license version number, you may choose any version ever published by
the Free Software Foundation.
14. If you wish to incorporate parts of the Library into other free
programs whose distribution conditions are incompatible with these,
write to the author to ask for permission. For software which is
copyrighted by the Free Software Foundation, write to the Free
Software Foundation; we sometimes make exceptions for this. Our
decision will be guided by the two goals of preserving the free status
of all derivatives of our free software and of promoting the sharing
and reuse of software generally.
NO WARRANTY
15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
DAMAGES.
END OF TERMS AND CONDITIONS
haxe_3.2.1+dfsg.orig/extra/all.hxml 0000664 0001750 0001750 00000000667 12607337712 017122 0 ustar andy andy 0000000 0000000 --no-output
--macro ImportAll.run()
-D doc-gen
--each
-neko all.n
-xml neko.xml
--next
-js all.js
-xml js.xml
--next
-swf all9.swf
-xml flash9.xml
-swf-version 11.4
--next
-php all_php
-xml php.xml
--next
-cpp all_cpp
-xml cpp.xml
-D xmldoc
-D HXCPP_MULTI_THREADED
--next
-java all_java
-xml java.xml
-D xmldoc
--next
-cs all_cs
-D unsafe
-xml cs.xml
-D xmldoc
--next
-python all_python
-xml python.xml
--next
-xml cross.xml
haxe_3.2.1+dfsg.orig/extra/all.hxproj 0000664 0001750 0001750 00000003215 12607337712 017454 0 ustar andy andy 0000000 0000000 
haxe all.hxml